diff options
Diffstat (limited to 'include/linux')
684 files changed, 24331 insertions, 9339 deletions
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index bcbdd7484e58..35e68358ad06 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -116,7 +116,7 @@ void acpi_numa_arch_fixup(void); #ifdef CONFIG_ACPI_HOTPLUG_CPU /* Arch dependent functions for cpu hotplug support */ -int acpi_map_lsapic(acpi_handle handle, int *pcpu); +int acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu); int acpi_unmap_lsapic(int cpu); #endif /* CONFIG_ACPI_HOTPLUG_CPU */ @@ -152,15 +152,6 @@ void acpi_penalize_isa_irq(int irq, int active); void acpi_pci_irq_disable (struct pci_dev *dev); -struct acpi_pci_driver { - struct list_head node; - int (*add)(struct acpi_pci_root *root); - void (*remove)(struct acpi_pci_root *root); -}; - -int acpi_pci_register_driver(struct acpi_pci_driver *driver); -void acpi_pci_unregister_driver(struct acpi_pci_driver *driver); - extern int ec_read(u8 addr, u8 *val); extern int ec_write(u8 addr, u8 val); extern int ec_transaction(u8 command, @@ -204,7 +195,7 @@ extern bool wmi_has_guid(const char *guid); #if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) extern long acpi_video_get_capabilities(acpi_handle graphics_dev_handle); -extern long acpi_is_video_device(struct acpi_device *device); +extern long acpi_is_video_device(acpi_handle handle); extern void acpi_video_dmi_promote_vendor(void); extern void acpi_video_dmi_demote_vendor(void); extern int acpi_video_backlight_support(void); @@ -217,7 +208,7 @@ static inline long acpi_video_get_capabilities(acpi_handle graphics_dev_handle) return 0; } -static inline long acpi_is_video_device(struct acpi_device *device) +static inline long acpi_is_video_device(acpi_handle handle) { return 0; } @@ -303,66 +294,58 @@ void __init acpi_nvs_nosave_s3(void); #endif /* CONFIG_PM_SLEEP */ struct acpi_osc_context { - char *uuid_str; /* uuid string */ + char *uuid_str; /* UUID string */ int rev; - struct acpi_buffer cap; /* arg2/arg3 */ - struct acpi_buffer ret; /* free by caller if success */ + struct acpi_buffer cap; /* list of DWORD capabilities */ + struct acpi_buffer ret; /* free by caller if success */ }; -#define OSC_QUERY_TYPE 0 -#define OSC_SUPPORT_TYPE 1 -#define OSC_CONTROL_TYPE 2 - -/* _OSC DW0 Definition */ -#define OSC_QUERY_ENABLE 1 -#define OSC_REQUEST_ERROR 2 -#define OSC_INVALID_UUID_ERROR 4 -#define OSC_INVALID_REVISION_ERROR 8 -#define OSC_CAPABILITIES_MASK_ERROR 16 - acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); -/* platform-wide _OSC bits */ -#define OSC_SB_PAD_SUPPORT 1 -#define OSC_SB_PPC_OST_SUPPORT 2 -#define OSC_SB_PR3_SUPPORT 4 -#define OSC_SB_HOTPLUG_OST_SUPPORT 8 -#define OSC_SB_APEI_SUPPORT 16 +/* Indexes into _OSC Capabilities Buffer (DWORDs 2 & 3 are device-specific) */ +#define OSC_QUERY_DWORD 0 /* DWORD 1 */ +#define OSC_SUPPORT_DWORD 1 /* DWORD 2 */ +#define OSC_CONTROL_DWORD 2 /* DWORD 3 */ + +/* _OSC Capabilities DWORD 1: Query/Control and Error Returns (generic) */ +#define OSC_QUERY_ENABLE 0x00000001 /* input */ +#define OSC_REQUEST_ERROR 0x00000002 /* return */ +#define OSC_INVALID_UUID_ERROR 0x00000004 /* return */ +#define OSC_INVALID_REVISION_ERROR 0x00000008 /* return */ +#define OSC_CAPABILITIES_MASK_ERROR 0x00000010 /* return */ + +/* Platform-Wide Capabilities _OSC: Capabilities DWORD 2: Support Field */ +#define OSC_SB_PAD_SUPPORT 0x00000001 +#define OSC_SB_PPC_OST_SUPPORT 0x00000002 +#define OSC_SB_PR3_SUPPORT 0x00000004 +#define OSC_SB_HOTPLUG_OST_SUPPORT 0x00000008 +#define OSC_SB_APEI_SUPPORT 0x00000010 +#define OSC_SB_CPC_SUPPORT 0x00000020 extern bool osc_sb_apei_support_acked; -/* PCI defined _OSC bits */ -/* _OSC DW1 Definition (OS Support Fields) */ -#define OSC_EXT_PCI_CONFIG_SUPPORT 1 -#define OSC_ACTIVE_STATE_PWR_SUPPORT 2 -#define OSC_CLOCK_PWR_CAPABILITY_SUPPORT 4 -#define OSC_PCI_SEGMENT_GROUPS_SUPPORT 8 -#define OSC_MSI_SUPPORT 16 -#define OSC_PCI_SUPPORT_MASKS 0x1f - -/* _OSC DW1 Definition (OS Control Fields) */ -#define OSC_PCI_EXPRESS_NATIVE_HP_CONTROL 1 -#define OSC_SHPC_NATIVE_HP_CONTROL 2 -#define OSC_PCI_EXPRESS_PME_CONTROL 4 -#define OSC_PCI_EXPRESS_AER_CONTROL 8 -#define OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL 16 - -#define OSC_PCI_CONTROL_MASKS (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | \ - OSC_SHPC_NATIVE_HP_CONTROL | \ - OSC_PCI_EXPRESS_PME_CONTROL | \ - OSC_PCI_EXPRESS_AER_CONTROL | \ - OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL) - -#define OSC_PCI_NATIVE_HOTPLUG (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | \ - OSC_SHPC_NATIVE_HP_CONTROL) +/* PCI Host Bridge _OSC: Capabilities DWORD 2: Support Field */ +#define OSC_PCI_EXT_CONFIG_SUPPORT 0x00000001 +#define OSC_PCI_ASPM_SUPPORT 0x00000002 +#define OSC_PCI_CLOCK_PM_SUPPORT 0x00000004 +#define OSC_PCI_SEGMENT_GROUPS_SUPPORT 0x00000008 +#define OSC_PCI_MSI_SUPPORT 0x00000010 +#define OSC_PCI_SUPPORT_MASKS 0x0000001f + +/* PCI Host Bridge _OSC: Capabilities DWORD 3: Control Field */ +#define OSC_PCI_EXPRESS_NATIVE_HP_CONTROL 0x00000001 +#define OSC_PCI_SHPC_NATIVE_HP_CONTROL 0x00000002 +#define OSC_PCI_EXPRESS_PME_CONTROL 0x00000004 +#define OSC_PCI_EXPRESS_AER_CONTROL 0x00000008 +#define OSC_PCI_EXPRESS_CAPABILITY_CONTROL 0x00000010 +#define OSC_PCI_CONTROL_MASKS 0x0000001f extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req); /* Enable _OST when all relevant hotplug operations are enabled */ #if defined(CONFIG_ACPI_HOTPLUG_CPU) && \ - (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \ - defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) && \ + defined(CONFIG_ACPI_HOTPLUG_MEMORY) && \ defined(CONFIG_ACPI_CONTAINER) #define ACPI_HOTPLUG_OST #endif @@ -491,6 +474,13 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control); + +void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state, + u32 val_a, u32 val_b)); + +acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, + u32 val_a, u32 val_b); + #ifdef CONFIG_X86 void arch_reserve_mem_area(acpi_physical_address addr, size_t size); #else diff --git a/include/linux/acpi_dma.h b/include/linux/acpi_dma.h new file mode 100644 index 000000000000..fb0298082916 --- /dev/null +++ b/include/linux/acpi_dma.h @@ -0,0 +1,120 @@ +/* + * ACPI helpers for DMA request / controller + * + * Based on of_dma.h + * + * Copyright (C) 2013, Intel Corporation + * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.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_ACPI_DMA_H +#define __LINUX_ACPI_DMA_H + +#include <linux/list.h> +#include <linux/device.h> +#include <linux/dmaengine.h> + +/** + * struct acpi_dma_spec - slave device DMA resources + * @chan_id: channel unique id + * @slave_id: request line unique id + * @dev: struct device of the DMA controller to be used in the filter + * function + */ +struct acpi_dma_spec { + int chan_id; + int slave_id; + struct device *dev; +}; + +/** + * struct acpi_dma - representation of the registered DMAC + * @dma_controllers: linked list node + * @dev: struct device of this controller + * @acpi_dma_xlate: callback function to find a suitable channel + * @data: private data used by a callback function + * @base_request_line: first supported request line (CSRT) + * @end_request_line: last supported request line (CSRT) + */ +struct acpi_dma { + struct list_head dma_controllers; + struct device *dev; + struct dma_chan *(*acpi_dma_xlate) + (struct acpi_dma_spec *, struct acpi_dma *); + void *data; + unsigned short base_request_line; + unsigned short end_request_line; +}; + +/* Used with acpi_dma_simple_xlate() */ +struct acpi_dma_filter_info { + dma_cap_mask_t dma_cap; + dma_filter_fn filter_fn; +}; + +#ifdef CONFIG_DMA_ACPI + +int acpi_dma_controller_register(struct device *dev, + struct dma_chan *(*acpi_dma_xlate) + (struct acpi_dma_spec *, struct acpi_dma *), + void *data); +int acpi_dma_controller_free(struct device *dev); +int devm_acpi_dma_controller_register(struct device *dev, + struct dma_chan *(*acpi_dma_xlate) + (struct acpi_dma_spec *, struct acpi_dma *), + void *data); +void devm_acpi_dma_controller_free(struct device *dev); + +struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev, + size_t index); +struct dma_chan *acpi_dma_request_slave_chan_by_name(struct device *dev, + const char *name); + +struct dma_chan *acpi_dma_simple_xlate(struct acpi_dma_spec *dma_spec, + struct acpi_dma *adma); +#else + +static inline int acpi_dma_controller_register(struct device *dev, + struct dma_chan *(*acpi_dma_xlate) + (struct acpi_dma_spec *, struct acpi_dma *), + void *data) +{ + return -ENODEV; +} +static inline int acpi_dma_controller_free(struct device *dev) +{ + return -ENODEV; +} +static inline int devm_acpi_dma_controller_register(struct device *dev, + struct dma_chan *(*acpi_dma_xlate) + (struct acpi_dma_spec *, struct acpi_dma *), + void *data) +{ + return -ENODEV; +} +static inline void devm_acpi_dma_controller_free(struct device *dev) +{ +} + +static inline struct dma_chan *acpi_dma_request_slave_chan_by_index( + struct device *dev, size_t index) +{ + return NULL; +} +static inline struct dma_chan *acpi_dma_request_slave_chan_by_name( + struct device *dev, const char *name) +{ + return NULL; +} + +#define acpi_dma_simple_xlate NULL + +#endif + +#define acpi_dma_request_slave_channel acpi_dma_request_slave_chan_by_index + +#endif /* __LINUX_ACPI_DMA_H */ diff --git a/include/linux/acpi_gpio.h b/include/linux/acpi_gpio.h index b76ebd08ff8e..4c120a1e0ca3 100644 --- a/include/linux/acpi_gpio.h +++ b/include/linux/acpi_gpio.h @@ -1,13 +1,25 @@ #ifndef _LINUX_ACPI_GPIO_H_ #define _LINUX_ACPI_GPIO_H_ +#include <linux/device.h> #include <linux/errno.h> #include <linux/gpio.h> +/** + * struct acpi_gpio_info - ACPI GPIO specific information + * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo + */ +struct acpi_gpio_info { + bool gpioint; +}; + #ifdef CONFIG_GPIO_ACPI int acpi_get_gpio(char *path, int pin); +int acpi_get_gpio_by_index(struct device *dev, int index, + struct acpi_gpio_info *info); void acpi_gpiochip_request_interrupts(struct gpio_chip *chip); +void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); #else /* CONFIG_GPIO_ACPI */ @@ -16,7 +28,14 @@ static inline int acpi_get_gpio(char *path, int pin) return -ENODEV; } +static inline int acpi_get_gpio_by_index(struct device *dev, int index, + struct acpi_gpio_info *info) +{ + return -ENODEV; +} + static inline void acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { } +static inline void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { } #endif /* CONFIG_GPIO_ACPI */ diff --git a/include/linux/aer.h b/include/linux/aer.h index ec10e1b24c1c..4dbaa7081530 100644 --- a/include/linux/aer.h +++ b/include/linux/aer.h @@ -7,6 +7,10 @@ #ifndef _AER_H_ #define _AER_H_ +#define AER_NONFATAL 0 +#define AER_FATAL 1 +#define AER_CORRECTABLE 2 + struct aer_header_log_regs { unsigned int dw0; unsigned int dw1; @@ -31,9 +35,9 @@ struct aer_capability_regs { #if defined(CONFIG_PCIEAER) /* pci-e port driver needs this function to enable aer */ -extern int pci_enable_pcie_error_reporting(struct pci_dev *dev); -extern int pci_disable_pcie_error_reporting(struct pci_dev *dev); -extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); +int pci_enable_pcie_error_reporting(struct pci_dev *dev); +int pci_disable_pcie_error_reporting(struct pci_dev *dev); +int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); #else static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev) { @@ -49,10 +53,11 @@ static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) } #endif -extern void cper_print_aer(const char *prefix, struct pci_dev *dev, - int cper_severity, struct aer_capability_regs *aer); -extern int cper_severity_to_aer(int cper_severity); -extern void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, - int severity); +void cper_print_aer(struct pci_dev *dev, int cper_severity, + struct aer_capability_regs *aer); +int cper_severity_to_aer(int cper_severity); +void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, + int severity, + struct aer_capability_regs *aer_regs); #endif //_AER_H_ diff --git a/include/linux/aio.h b/include/linux/aio.h index 31ff6dba4872..9f4b10a81f8a 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h @@ -9,115 +9,45 @@ #include <linux/atomic.h> -#define AIO_MAXSEGS 4 -#define AIO_KIOGRP_NR_ATOMIC 8 - struct kioctx; +struct kiocb; -/* Notes on cancelling a kiocb: - * If a kiocb is cancelled, aio_complete may return 0 to indicate - * that cancel has not yet disposed of the kiocb. All cancel - * operations *must* call aio_put_req to dispose of the kiocb - * to guard against races with the completion code. - */ -#define KIOCB_C_CANCELLED 0x01 -#define KIOCB_C_COMPLETE 0x02 - -#define KIOCB_SYNC_KEY (~0U) +#define KIOCB_KEY 0 -/* ki_flags bits */ /* - * This may be used for cancel/retry serialization in the future, but - * for now it's unused and we probably don't want modules to even - * think they can use it. + * We use ki_cancel == KIOCB_CANCELLED to indicate that a kiocb has been either + * cancelled or completed (this makes a certain amount of sense because + * successful cancellation - io_cancel() - does deliver the completion to + * userspace). + * + * And since most things don't implement kiocb cancellation and we'd really like + * kiocb completion to be lockless when possible, we use ki_cancel to + * synchronize cancellation and completion - we only set it to KIOCB_CANCELLED + * with xchg() or cmpxchg(), see batch_complete_aio() and kiocb_cancel(). */ -/* #define KIF_LOCKED 0 */ -#define KIF_KICKED 1 -#define KIF_CANCELLED 2 - -#define kiocbTryLock(iocb) test_and_set_bit(KIF_LOCKED, &(iocb)->ki_flags) -#define kiocbTryKick(iocb) test_and_set_bit(KIF_KICKED, &(iocb)->ki_flags) - -#define kiocbSetLocked(iocb) set_bit(KIF_LOCKED, &(iocb)->ki_flags) -#define kiocbSetKicked(iocb) set_bit(KIF_KICKED, &(iocb)->ki_flags) -#define kiocbSetCancelled(iocb) set_bit(KIF_CANCELLED, &(iocb)->ki_flags) +#define KIOCB_CANCELLED ((void *) (~0ULL)) -#define kiocbClearLocked(iocb) clear_bit(KIF_LOCKED, &(iocb)->ki_flags) -#define kiocbClearKicked(iocb) clear_bit(KIF_KICKED, &(iocb)->ki_flags) -#define kiocbClearCancelled(iocb) clear_bit(KIF_CANCELLED, &(iocb)->ki_flags) +typedef int (kiocb_cancel_fn)(struct kiocb *); -#define kiocbIsLocked(iocb) test_bit(KIF_LOCKED, &(iocb)->ki_flags) -#define kiocbIsKicked(iocb) test_bit(KIF_KICKED, &(iocb)->ki_flags) -#define kiocbIsCancelled(iocb) test_bit(KIF_CANCELLED, &(iocb)->ki_flags) - -/* is there a better place to document function pointer methods? */ -/** - * ki_retry - iocb forward progress callback - * @kiocb: The kiocb struct to advance by performing an operation. - * - * This callback is called when the AIO core wants a given AIO operation - * to make forward progress. The kiocb argument describes the operation - * that is to be performed. As the operation proceeds, perhaps partially, - * ki_retry is expected to update the kiocb with progress made. Typically - * ki_retry is set in the AIO core and it itself calls file_operations - * helpers. - * - * ki_retry's return value determines when the AIO operation is completed - * and an event is generated in the AIO event ring. Except the special - * return values described below, the value that is returned from ki_retry - * is transferred directly into the completion ring as the operation's - * resulting status. Once this has happened ki_retry *MUST NOT* reference - * the kiocb pointer again. - * - * If ki_retry returns -EIOCBQUEUED it has made a promise that aio_complete() - * will be called on the kiocb pointer in the future. The AIO core will - * not ask the method again -- ki_retry must ensure forward progress. - * aio_complete() must be called once and only once in the future, multiple - * calls may result in undefined behaviour. - * - * If ki_retry returns -EIOCBRETRY it has made a promise that kick_iocb() - * will be called on the kiocb pointer in the future. This may happen - * through generic helpers that associate kiocb->ki_wait with a wait - * queue head that ki_retry uses via current->io_wait. It can also happen - * with custom tracking and manual calls to kick_iocb(), though that is - * discouraged. In either case, kick_iocb() must be called once and only - * once. ki_retry must ensure forward progress, the AIO core will wait - * indefinitely for kick_iocb() to be called. - */ struct kiocb { - struct list_head ki_run_list; - unsigned long ki_flags; - int ki_users; - unsigned ki_key; /* id of this request */ - struct file *ki_filp; - struct kioctx *ki_ctx; /* may be NULL for sync ops */ - int (*ki_cancel)(struct kiocb *, struct io_event *); - ssize_t (*ki_retry)(struct kiocb *); - void (*ki_dtor)(struct kiocb *); + struct kioctx *ki_ctx; /* NULL for sync ops, + * -1 for kernel caller */ + kiocb_cancel_fn *ki_cancel; + void *private; union { void __user *user; struct task_struct *tsk; + void (*complete)(u64 user_data, long res); } ki_obj; __u64 ki_user_data; /* user's data for completion */ loff_t ki_pos; - - void *private; - /* State that we remember to be able to restart/retry */ - unsigned short ki_opcode; - size_t ki_nbytes; /* copy of iocb->aio_nbytes */ - char __user *ki_buf; /* remaining iocb->aio_buf */ - size_t ki_left; /* remaining bytes */ - struct iovec ki_inline_vec; /* inline vector */ - struct iovec *ki_iovec; - unsigned long ki_nr_segs; - unsigned long ki_cur_seg; + size_t ki_nbytes; /* copy of iocb->aio_nbytes */ struct list_head ki_list; /* the aio core uses this * for cancellation */ - struct list_head ki_batch; /* batch allocation */ /* * If the aio_resfd field of the userspace iocb is not zero, @@ -128,106 +58,50 @@ struct kiocb { static inline bool is_sync_kiocb(struct kiocb *kiocb) { - return kiocb->ki_key == KIOCB_SYNC_KEY; + return kiocb->ki_ctx == NULL; +} + +static inline bool is_kernel_kiocb(struct kiocb *kiocb) +{ + return kiocb->ki_ctx == (void *)-1; } static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) { *kiocb = (struct kiocb) { - .ki_users = 1, - .ki_key = KIOCB_SYNC_KEY, + .ki_ctx = NULL, .ki_filp = filp, .ki_obj.tsk = current, }; } -#define AIO_RING_MAGIC 0xa10a10a1 -#define AIO_RING_COMPAT_FEATURES 1 -#define AIO_RING_INCOMPAT_FEATURES 0 -struct aio_ring { - unsigned id; /* kernel internal index number */ - unsigned nr; /* number of io_events */ - unsigned head; - unsigned tail; - - unsigned magic; - unsigned compat_features; - unsigned incompat_features; - unsigned header_length; /* size of aio_ring */ - - - struct io_event io_events[0]; -}; /* 128 bytes + ring size */ - -#define AIO_RING_PAGES 8 -struct aio_ring_info { - unsigned long mmap_base; - unsigned long mmap_size; - - struct page **ring_pages; - spinlock_t ring_lock; - long nr_pages; - - unsigned nr, tail; - - struct page *internal_pages[AIO_RING_PAGES]; -}; - -static inline unsigned aio_ring_avail(struct aio_ring_info *info, - struct aio_ring *ring) -{ - return (ring->head + info->nr - 1 - ring->tail) % info->nr; -} - -struct kioctx { - atomic_t users; - int dead; - struct mm_struct *mm; - - /* This needs improving */ - unsigned long user_id; - struct hlist_node list; - - wait_queue_head_t wait; - - spinlock_t ctx_lock; - - int reqs_active; - struct list_head active_reqs; /* used for cancellation */ - struct list_head run_list; /* used for kicked reqs */ - - /* sys_io_setup currently limits this to an unsigned int */ - unsigned max_reqs; - - struct aio_ring_info ring_info; - - struct delayed_work wq; - - struct rcu_head rcu_head; -}; - /* prototypes */ -extern unsigned aio_max_size; - #ifdef CONFIG_AIO extern ssize_t wait_on_sync_kiocb(struct kiocb *iocb); -extern int aio_put_req(struct kiocb *iocb); -extern void kick_iocb(struct kiocb *iocb); -extern int aio_complete(struct kiocb *iocb, long res, long res2); +extern void aio_complete(struct kiocb *iocb, long res, long res2); struct mm_struct; extern void exit_aio(struct mm_struct *mm); extern long do_io_submit(aio_context_t ctx_id, long nr, struct iocb __user *__user *iocbpp, bool compat); +void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel); +struct kiocb *aio_kernel_alloc(gfp_t gfp); +void aio_kernel_free(struct kiocb *iocb); +void aio_kernel_init_rw(struct kiocb *iocb, struct file *filp, size_t nr, + loff_t off); +void aio_kernel_init_callback(struct kiocb *iocb, + void (*complete)(u64 user_data, long res), + u64 user_data); +int aio_kernel_submit(struct kiocb *iocb, unsigned short op, void *ptr); #else static inline ssize_t wait_on_sync_kiocb(struct kiocb *iocb) { return 0; } -static inline int aio_put_req(struct kiocb *iocb) { return 0; } -static inline void kick_iocb(struct kiocb *iocb) { } -static inline int aio_complete(struct kiocb *iocb, long res, long res2) { return 0; } +static inline void aio_complete(struct kiocb *iocb, long res, long res2) { } struct mm_struct; static inline void exit_aio(struct mm_struct *mm) { } static inline long do_io_submit(aio_context_t ctx_id, long nr, struct iocb __user * __user *iocbpp, bool compat) { return 0; } +static inline void kiocb_set_cancel_fn(struct kiocb *req, + kiocb_cancel_fn *cancel) { } #endif /* CONFIG_AIO */ static inline struct kiocb *list_kiocb(struct list_head *h) diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h index 9069694e70eb..a899402a5a0e 100644 --- a/include/linux/alarmtimer.h +++ b/include/linux/alarmtimer.h @@ -44,10 +44,14 @@ struct alarm { void alarm_init(struct alarm *alarm, enum alarmtimer_type type, enum alarmtimer_restart (*function)(struct alarm *, ktime_t)); int alarm_start(struct alarm *alarm, ktime_t start); +int alarm_start_relative(struct alarm *alarm, ktime_t start); +void alarm_restart(struct alarm *alarm); int alarm_try_to_cancel(struct alarm *alarm); int alarm_cancel(struct alarm *alarm); u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval); +u64 alarm_forward_now(struct alarm *alarm, ktime_t interval); +ktime_t alarm_expires_remaining(const struct alarm *alarm); /* Provide way to access the rtc device being used by alarmtimers */ struct rtc_device *alarmtimer_get_rtcdev(void); diff --git a/include/linux/amba/pl080.h b/include/linux/amba/pl080.h index 3e7b62fbefbd..91b84a7f0539 100644 --- a/include/linux/amba/pl080.h +++ b/include/linux/amba/pl080.h @@ -87,6 +87,7 @@ #define PL080_CONTROL_SB_SIZE_MASK (0x7 << 12) #define PL080_CONTROL_SB_SIZE_SHIFT (12) #define PL080_CONTROL_TRANSFER_SIZE_MASK (0xfff << 0) +#define PL080S_CONTROL_TRANSFER_SIZE_MASK (0x1ffffff << 0) #define PL080_CONTROL_TRANSFER_SIZE_SHIFT (0) #define PL080_BSIZE_1 (0x0) diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h index 2a5f64a11b77..10fe2a211c2e 100644 --- a/include/linux/amba/pl08x.h +++ b/include/linux/amba/pl08x.h @@ -76,11 +76,11 @@ struct pl08x_channel_data { * platform, all inclusive, including multiplexed channels. The available * physical channels will be multiplexed around these signals as they are * requested, just enumerate all possible channels. - * @get_signal: request a physical signal to be used for a DMA transfer + * @get_xfer_signal: request a physical signal to be used for a DMA transfer * immediately: if there is some multiplexing or similar blocking the use * of the channel the transfer can be denied by returning less than zero, * else it returns the allocated signal number - * @put_signal: indicate to the platform that this physical signal is not + * @put_xfer_signal: indicate to the platform that this physical signal is not * running any DMA transfer and multiplexing can be recycled * @lli_buses: buses which LLIs can be fetched from: PL08X_AHB1 | PL08X_AHB2 * @mem_buses: buses which memory can be accessed from: PL08X_AHB1 | PL08X_AHB2 @@ -89,8 +89,8 @@ struct pl08x_platform_data { const struct pl08x_channel_data *slave_channels; unsigned int num_slave_channels; struct pl08x_channel_data memcpy_channel; - int (*get_signal)(const struct pl08x_channel_data *); - void (*put_signal)(const struct pl08x_channel_data *, int); + int (*get_xfer_signal)(const struct pl08x_channel_data *); + void (*put_xfer_signal)(const struct pl08x_channel_data *, int); u8 lli_buses; u8 mem_buses; }; diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h index f612c783170f..62d9303c2837 100644 --- a/include/linux/amba/serial.h +++ b/include/linux/amba/serial.h @@ -203,6 +203,9 @@ struct amba_pl011_data { bool (*dma_filter)(struct dma_chan *chan, void *filter_param); void *dma_rx_param; void *dma_tx_param; + bool dma_rx_poll_enable; + unsigned int dma_rx_poll_rate; + unsigned int dma_rx_poll_timeout; void (*init) (void); void (*exit) (void); }; diff --git a/include/linux/anon_inodes.h b/include/linux/anon_inodes.h index 8013a45242fe..cf573c22b81e 100644 --- a/include/linux/anon_inodes.h +++ b/include/linux/anon_inodes.h @@ -13,6 +13,9 @@ struct file_operations; struct file *anon_inode_getfile(const char *name, const struct file_operations *fops, void *priv, int flags); +struct file *anon_inode_getfile_private(const char *name, + const struct file_operations *fops, + void *priv, int flags); int anon_inode_getfd(const char *name, const struct file_operations *fops, void *priv, int flags); diff --git a/include/linux/arm-cci.h b/include/linux/arm-cci.h new file mode 100644 index 000000000000..79d6edf446d5 --- /dev/null +++ b/include/linux/arm-cci.h @@ -0,0 +1,61 @@ +/* + * CCI cache coherent interconnect support + * + * Copyright (C) 2013 ARM Ltd. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LINUX_ARM_CCI_H +#define __LINUX_ARM_CCI_H + +#include <linux/errno.h> +#include <linux/types.h> + +struct device_node; + +#ifdef CONFIG_ARM_CCI +extern bool cci_probed(void); +extern int cci_ace_get_port(struct device_node *dn); +extern int cci_disable_port_by_cpu(u64 mpidr); +extern int __cci_control_port_by_device(struct device_node *dn, bool enable); +extern int __cci_control_port_by_index(u32 port, bool enable); +#else +static inline bool cci_probed(void) { return false; } +static inline int cci_ace_get_port(struct device_node *dn) +{ + return -ENODEV; +} +static inline int cci_disable_port_by_cpu(u64 mpidr) { return -ENODEV; } +static inline int __cci_control_port_by_device(struct device_node *dn, + bool enable) +{ + return -ENODEV; +} +static inline int __cci_control_port_by_index(u32 port, bool enable) +{ + return -ENODEV; +} +#endif +#define cci_disable_port_by_device(dev) \ + __cci_control_port_by_device(dev, false) +#define cci_enable_port_by_device(dev) \ + __cci_control_port_by_device(dev, true) +#define cci_disable_port_by_index(dev) \ + __cci_control_port_by_index(dev, false) +#define cci_enable_port_by_index(dev) \ + __cci_control_port_by_index(dev, true) + +#endif diff --git a/include/linux/async.h b/include/linux/async.h index a2e3f18b2ad6..6b0226bdaadc 100644 --- a/include/linux/async.h +++ b/include/linux/async.h @@ -16,9 +16,8 @@ #include <linux/list.h> typedef u64 async_cookie_t; -typedef void (async_func_ptr) (void *data, async_cookie_t cookie); +typedef void (*async_func_t) (void *data, async_cookie_t cookie); struct async_domain { - struct list_head node; struct list_head pending; unsigned registered:1; }; @@ -27,8 +26,7 @@ struct async_domain { * domain participates in global async_synchronize_full */ #define ASYNC_DOMAIN(_name) \ - struct async_domain _name = { .node = LIST_HEAD_INIT(_name.node), \ - .pending = LIST_HEAD_INIT(_name.pending), \ + struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \ .registered = 1 } /* @@ -36,12 +34,11 @@ struct async_domain { * complete, this domain does not participate in async_synchronize_full */ #define ASYNC_DOMAIN_EXCLUSIVE(_name) \ - struct async_domain _name = { .node = LIST_HEAD_INIT(_name.node), \ - .pending = LIST_HEAD_INIT(_name.pending), \ + struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \ .registered = 0 } -extern async_cookie_t async_schedule(async_func_ptr *ptr, void *data); -extern async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, +extern async_cookie_t async_schedule(async_func_t func, void *data); +extern async_cookie_t async_schedule_domain(async_func_t func, void *data, struct async_domain *domain); void async_unregister_domain(struct async_domain *domain); extern void async_synchronize_full(void); diff --git a/include/linux/async_tx.h b/include/linux/async_tx.h index a1c486a88e88..179b38ffd351 100644 --- a/include/linux/async_tx.h +++ b/include/linux/async_tx.h @@ -182,10 +182,6 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset, unsigned int src_offset, size_t len, struct async_submit_ctl *submit); -struct dma_async_tx_descriptor * -async_memset(struct page *dest, int val, unsigned int offset, - size_t len, struct async_submit_ctl *submit); - struct dma_async_tx_descriptor *async_trigger_callback(struct async_submit_ctl *submit); struct dma_async_tx_descriptor * diff --git a/include/linux/ata.h b/include/linux/ata.h index 8f7a3d68371a..bf4c69ca76df 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -239,6 +239,8 @@ enum { ATA_CMD_WRITE_QUEUED_FUA_EXT = 0x3E, ATA_CMD_FPDMA_READ = 0x60, ATA_CMD_FPDMA_WRITE = 0x61, + ATA_CMD_FPDMA_SEND = 0x64, + ATA_CMD_FPDMA_RECV = 0x65, ATA_CMD_PIO_READ = 0x20, ATA_CMD_PIO_READ_EXT = 0x24, ATA_CMD_PIO_WRITE = 0x30, @@ -293,8 +295,13 @@ enum { /* marked obsolete in the ATA/ATAPI-7 spec */ ATA_CMD_RESTORE = 0x10, + /* Subcmds for ATA_CMD_FPDMA_SEND */ + ATA_SUBCMD_FPDMA_SEND_DSM = 0x00, + ATA_SUBCMD_FPDMA_SEND_WR_LOG_DMA_EXT = 0x02, + /* READ_LOG_EXT pages */ ATA_LOG_SATA_NCQ = 0x10, + ATA_LOG_NCQ_SEND_RECV = 0x13, ATA_LOG_SATA_ID_DEV_DATA = 0x30, ATA_LOG_SATA_SETTINGS = 0x08, ATA_LOG_DEVSLP_OFFSET = 0x30, @@ -305,6 +312,15 @@ enum { ATA_LOG_DEVSLP_VALID = 0x07, ATA_LOG_DEVSLP_VALID_MASK = 0x80, + /* NCQ send and receive log */ + ATA_LOG_NCQ_SEND_RECV_SUBCMDS_OFFSET = 0x00, + ATA_LOG_NCQ_SEND_RECV_SUBCMDS_DSM = (1 << 0), + ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET = 0x04, + ATA_LOG_NCQ_SEND_RECV_DSM_TRIM = (1 << 0), + ATA_LOG_NCQ_SEND_RECV_RD_LOG_OFFSET = 0x08, + ATA_LOG_NCQ_SEND_RECV_WR_LOG_OFFSET = 0x0C, + ATA_LOG_NCQ_SEND_RECV_SIZE = 0x10, + /* READ/WRITE LONG (obsolete) */ ATA_CMD_READ_LONG = 0x22, ATA_CMD_READ_LONG_ONCE = 0x23, @@ -446,22 +462,6 @@ enum { SERR_TRANS_ST_ERROR = (1 << 24), /* Transport state trans. error */ SERR_UNRECOG_FIS = (1 << 25), /* Unrecognized FIS */ SERR_DEV_XCHG = (1 << 26), /* device exchanged */ - - /* struct ata_taskfile flags */ - ATA_TFLAG_LBA48 = (1 << 0), /* enable 48-bit LBA and "HOB" */ - ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */ - ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */ - ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */ - ATA_TFLAG_LBA = (1 << 4), /* enable LBA */ - ATA_TFLAG_FUA = (1 << 5), /* enable FUA */ - ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */ - - /* protocol flags */ - ATA_PROT_FLAG_PIO = (1 << 0), /* is PIO */ - ATA_PROT_FLAG_DMA = (1 << 1), /* is DMA */ - ATA_PROT_FLAG_DATA = ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA, - ATA_PROT_FLAG_NCQ = (1 << 2), /* is NCQ */ - ATA_PROT_FLAG_ATAPI = (1 << 3), /* is ATAPI */ }; enum ata_tf_protocols { @@ -488,83 +488,6 @@ struct ata_bmdma_prd { __le32 flags_len; }; -struct ata_taskfile { - unsigned long flags; /* ATA_TFLAG_xxx */ - u8 protocol; /* ATA_PROT_xxx */ - - u8 ctl; /* control reg */ - - u8 hob_feature; /* additional data */ - u8 hob_nsect; /* to support LBA48 */ - u8 hob_lbal; - u8 hob_lbam; - u8 hob_lbah; - - u8 feature; - u8 nsect; - u8 lbal; - u8 lbam; - u8 lbah; - - u8 device; - - u8 command; /* IO operation */ -}; - -/* - * protocol tests - */ -static inline unsigned int ata_prot_flags(u8 prot) -{ - switch (prot) { - case ATA_PROT_NODATA: - return 0; - case ATA_PROT_PIO: - return ATA_PROT_FLAG_PIO; - case ATA_PROT_DMA: - return ATA_PROT_FLAG_DMA; - case ATA_PROT_NCQ: - return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ; - case ATAPI_PROT_NODATA: - return ATA_PROT_FLAG_ATAPI; - case ATAPI_PROT_PIO: - return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO; - case ATAPI_PROT_DMA: - return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA; - } - return 0; -} - -static inline int ata_is_atapi(u8 prot) -{ - return ata_prot_flags(prot) & ATA_PROT_FLAG_ATAPI; -} - -static inline int ata_is_nodata(u8 prot) -{ - return !(ata_prot_flags(prot) & ATA_PROT_FLAG_DATA); -} - -static inline int ata_is_pio(u8 prot) -{ - return ata_prot_flags(prot) & ATA_PROT_FLAG_PIO; -} - -static inline int ata_is_dma(u8 prot) -{ - return ata_prot_flags(prot) & ATA_PROT_FLAG_DMA; -} - -static inline int ata_is_ncq(u8 prot) -{ - return ata_prot_flags(prot) & ATA_PROT_FLAG_NCQ; -} - -static inline int ata_is_data(u8 prot) -{ - return ata_prot_flags(prot) & ATA_PROT_FLAG_DATA; -} - /* * id tests */ @@ -865,6 +788,11 @@ static inline int ata_id_rotation_rate(const u16 *id) return val; } +static inline bool ata_id_has_ncq_send_and_recv(const u16 *id) +{ + return id[ATA_ID_SATA_CAPABILITY_2] & BIT(6); +} + static inline bool ata_id_has_trim(const u16 *id) { if (ata_id_major_version(id) >= 7 && @@ -954,7 +882,7 @@ static inline int atapi_cdb_len(const u16 *dev_id) } } -static inline bool atapi_command_packet_set(const u16 *dev_id) +static inline int atapi_command_packet_set(const u16 *dev_id) { return (dev_id[ATA_ID_CONFIG] >> 8) & 0x1f; } @@ -1060,15 +988,6 @@ static inline unsigned ata_set_lba_range_entries(void *_buffer, return used_bytes; } -static inline int is_multi_taskfile(struct ata_taskfile *tf) -{ - return (tf->command == ATA_CMD_READ_MULTI) || - (tf->command == ATA_CMD_WRITE_MULTI) || - (tf->command == ATA_CMD_READ_MULTI_EXT) || - (tf->command == ATA_CMD_WRITE_MULTI_EXT) || - (tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT); -} - static inline bool ata_ok(u8 status) { return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR)) diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h index deb0ae58b99b..66a0e5384edd 100644 --- a/include/linux/atmel-ssc.h +++ b/include/linux/atmel-ssc.h @@ -11,7 +11,7 @@ struct atmel_ssc_platform_data { struct ssc_device { struct list_head list; - resource_size_t phybase; + dma_addr_t phybase; void __iomem *regs; struct platform_device *pdev; struct atmel_ssc_platform_data *pdata; diff --git a/include/linux/atmel_serial.h b/include/linux/atmel_serial.h index fd6833764d72..be201ca2990c 100644 --- a/include/linux/atmel_serial.h +++ b/include/linux/atmel_serial.h @@ -124,4 +124,6 @@ #define ATMEL_US_NER 0x44 /* Number of Errors Register */ #define ATMEL_US_IF 0x4c /* IrDA Filter Register */ +#define ATMEL_US_NAME 0xf0 /* Ip Name */ + #endif diff --git a/include/linux/audit.h b/include/linux/audit.h index 5a6d718adf34..729a4d165bcc 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -84,8 +84,13 @@ extern int audit_classify_arch(int arch); #define AUDIT_TYPE_CHILD_DELETE 3 /* a child being deleted */ #define AUDIT_TYPE_CHILD_CREATE 4 /* a child being created */ +/* maximized args number that audit_socketcall can process */ +#define AUDITSC_ARGS 6 + struct filename; +extern void audit_log_session_info(struct audit_buffer *ab); + #ifdef CONFIG_AUDITSYSCALL /* These are defined in auditsc.c */ /* Public API */ @@ -98,8 +103,11 @@ extern void __audit_syscall_exit(int ret_success, long ret_value); extern struct filename *__audit_reusename(const __user char *uptr); extern void __audit_getname(struct filename *name); extern void audit_putname(struct filename *name); + +#define AUDIT_INODE_PARENT 1 /* dentry represents the parent */ +#define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */ extern void __audit_inode(struct filename *name, const struct dentry *dentry, - unsigned int parent); + unsigned int flags); extern void __audit_inode_child(const struct inode *parent, const struct dentry *dentry, const unsigned char type); @@ -120,7 +128,7 @@ static inline void audit_syscall_entry(int arch, int major, unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3) { - if (unlikely(!audit_dummy_context())) + if (unlikely(current->audit_context)) __audit_syscall_entry(arch, major, a0, a1, a2, a3); } static inline void audit_syscall_exit(void *pt_regs) @@ -143,10 +151,22 @@ static inline void audit_getname(struct filename *name) if (unlikely(!audit_dummy_context())) __audit_getname(name); } -static inline void audit_inode(struct filename *name, const struct dentry *dentry, +static inline void audit_inode(struct filename *name, + const struct dentry *dentry, unsigned int parent) { + if (unlikely(!audit_dummy_context())) { + unsigned int flags = 0; + if (parent) + flags |= AUDIT_INODE_PARENT; + __audit_inode(name, dentry, flags); + } +} +static inline void audit_inode_parent_hidden(struct filename *name, + const struct dentry *dentry) +{ if (unlikely(!audit_dummy_context())) - __audit_inode(name, dentry, parent); + __audit_inode(name, dentry, + AUDIT_INODE_PARENT | AUDIT_INODE_HIDDEN); } static inline void audit_inode_child(const struct inode *parent, const struct dentry *dentry, @@ -185,12 +205,10 @@ static inline int audit_get_sessionid(struct task_struct *tsk) return tsk->sessionid; } -extern void audit_log_task_context(struct audit_buffer *ab); -extern void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk); extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp); extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode); extern int __audit_bprm(struct linux_binprm *bprm); -extern void __audit_socketcall(int nargs, unsigned long *args); +extern int __audit_socketcall(int nargs, unsigned long *args); extern int __audit_sockaddr(int len, void *addr); extern void __audit_fd_pair(int fd1, int fd2); extern void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr); @@ -224,10 +242,11 @@ static inline int audit_bprm(struct linux_binprm *bprm) return __audit_bprm(bprm); return 0; } -static inline void audit_socketcall(int nargs, unsigned long *args) +static inline int audit_socketcall(int nargs, unsigned long *args) { if (unlikely(!audit_dummy_context())) - __audit_socketcall(nargs, args); + return __audit_socketcall(nargs, args); + return 0; } static inline int audit_sockaddr(int len, void *addr) { @@ -307,7 +326,7 @@ static inline void audit_putname(struct filename *name) { } static inline void __audit_inode(struct filename *name, const struct dentry *dentry, - unsigned int parent) + unsigned int flags) { } static inline void __audit_inode_child(const struct inode *parent, const struct dentry *dentry, @@ -317,6 +336,9 @@ static inline void audit_inode(struct filename *name, const struct dentry *dentry, unsigned int parent) { } +static inline void audit_inode_parent_hidden(struct filename *name, + const struct dentry *dentry) +{ } static inline void audit_inode_child(const struct inode *parent, const struct dentry *dentry, const unsigned char type) @@ -340,11 +362,6 @@ static inline int audit_get_sessionid(struct task_struct *tsk) { return -1; } -static inline void audit_log_task_context(struct audit_buffer *ab) -{ } -static inline void audit_log_task_info(struct audit_buffer *ab, - struct task_struct *tsk) -{ } static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) { } static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, @@ -354,8 +371,10 @@ static inline int audit_bprm(struct linux_binprm *bprm) { return 0; } -static inline void audit_socketcall(int nargs, unsigned long *args) -{ } +static inline int audit_socketcall(int nargs, unsigned long *args) +{ + return 0; +} static inline void audit_fd_pair(int fd1, int fd2) { } static inline int audit_sockaddr(int len, void *addr) @@ -390,6 +409,11 @@ static inline void audit_ptrace(struct task_struct *t) #define audit_signals 0 #endif /* CONFIG_AUDITSYSCALL */ +static inline bool audit_loginuid_set(struct task_struct *tsk) +{ + return uid_valid(audit_get_loginuid(tsk)); +} + #ifdef CONFIG_AUDIT /* These are defined in audit.c */ /* Public API */ @@ -429,14 +453,17 @@ static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) { } #endif +extern int audit_log_task_context(struct audit_buffer *ab); +extern void audit_log_task_info(struct audit_buffer *ab, + struct task_struct *tsk); + extern int audit_update_lsm_rules(void); /* Private API (for audit.c only) */ -extern int audit_filter_user(void); +extern int audit_filter_user(int type); extern int audit_filter_type(int type); extern int audit_receive_filter(int type, int pid, int seq, - void *data, size_t datasz, kuid_t loginuid, - u32 sessionid, u32 sid); + void *data, size_t datasz); extern int audit_enabled; #else /* CONFIG_AUDIT */ static inline __printf(4, 5) @@ -476,6 +503,13 @@ static inline void audit_log_link_denied(const char *string, { } static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) { } +static inline int audit_log_task_context(struct audit_buffer *ab) +{ + return 0; +} +static inline void audit_log_task_info(struct audit_buffer *ab, + struct task_struct *tsk) +{ } #define audit_enabled 0 #endif /* CONFIG_AUDIT */ static inline void audit_log_string(struct audit_buffer *ab, const char *buf) diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index 350459910fe1..5f66d519a726 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -18,6 +18,7 @@ #include <linux/writeback.h> #include <linux/atomic.h> #include <linux/sysctl.h> +#include <linux/workqueue.h> struct page; struct device; @@ -27,7 +28,6 @@ struct dentry; * Bits in backing_dev_info.state */ enum bdi_state { - BDI_pending, /* On its way to being activated */ BDI_wb_alloc, /* Default embedded wb allocated */ BDI_async_congested, /* The async (write) queue is getting full */ BDI_sync_congested, /* The sync queue is getting full */ @@ -53,10 +53,8 @@ struct bdi_writeback { unsigned int nr; unsigned long last_old_flush; /* last old data flush */ - unsigned long last_active; /* last time bdi thread was active */ - struct task_struct *task; /* writeback thread */ - struct timer_list wakeup_timer; /* used for delayed bdi thread wakeup */ + struct delayed_work dwork; /* work item used for writeback */ struct list_head b_dirty; /* dirty inodes */ struct list_head b_io; /* parked for writeback */ struct list_head b_more_io; /* parked for more writeback */ @@ -123,14 +121,15 @@ int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int); void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, enum wb_reason reason); void bdi_start_background_writeback(struct backing_dev_info *bdi); -int bdi_writeback_thread(void *data); +void bdi_writeback_workfn(struct work_struct *work); int bdi_has_dirty_io(struct backing_dev_info *bdi); void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi); void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2); extern spinlock_t bdi_lock; extern struct list_head bdi_list; -extern struct list_head bdi_pending_list; + +extern struct workqueue_struct *bdi_wq; static inline int wb_has_dirty_io(struct bdi_writeback *wb) { @@ -244,6 +243,8 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio); * BDI_CAP_EXEC_MAP: Can be mapped for execution * * BDI_CAP_SWAP_BACKED: Count shmem/tmpfs objects as swap-backed. + * + * BDI_CAP_STRICTLIMIT: Keep number of dirty pages below bdi threshold. */ #define BDI_CAP_NO_ACCT_DIRTY 0x00000001 #define BDI_CAP_NO_WRITEBACK 0x00000002 @@ -255,6 +256,7 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio); #define BDI_CAP_NO_ACCT_WB 0x00000080 #define BDI_CAP_SWAP_BACKED 0x00000100 #define BDI_CAP_STABLE_WRITES 0x00000200 +#define BDI_CAP_STRICTLIMIT 0x00000400 #define BDI_CAP_VMFLAGS \ (BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP) @@ -336,11 +338,6 @@ static inline bool bdi_cap_swap_backed(struct backing_dev_info *bdi) return bdi->capabilities & BDI_CAP_SWAP_BACKED; } -static inline bool bdi_cap_flush_forker(struct backing_dev_info *bdi) -{ - return bdi == &default_backing_dev_info; -} - static inline bool mapping_cap_writeback_dirty(struct address_space *mapping) { return bdi_cap_writeback_dirty(mapping->backing_dev_info); diff --git a/include/linux/backlight.h b/include/linux/backlight.h index da9a0825e007..53b77949c79d 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h @@ -114,7 +114,13 @@ static inline void backlight_update_status(struct backlight_device *bd) extern struct backlight_device *backlight_device_register(const char *name, struct device *dev, void *devdata, const struct backlight_ops *ops, const struct backlight_properties *props); +extern struct backlight_device *devm_backlight_device_register( + struct device *dev, const char *name, struct device *parent, + void *devdata, const struct backlight_ops *ops, + const struct backlight_properties *props); extern void backlight_device_unregister(struct backlight_device *bd); +extern void devm_backlight_device_unregister(struct device *dev, + struct backlight_device *bd); extern void backlight_force_update(struct backlight_device *bd, enum backlight_update_reason reason); diff --git a/include/linux/basic_mmio_gpio.h b/include/linux/basic_mmio_gpio.h index 1c504ca5bdb3..d8a97ec0e2b8 100644 --- a/include/linux/basic_mmio_gpio.h +++ b/include/linux/basic_mmio_gpio.h @@ -72,5 +72,6 @@ int bgpio_init(struct bgpio_chip *bgc, struct device *dev, #define BGPIOF_BIG_ENDIAN BIT(0) #define BGPIOF_UNREADABLE_REG_SET BIT(1) /* reg_set is unreadable */ #define BGPIOF_UNREADABLE_REG_DIR BIT(2) /* reg_dir is unreadable */ +#define BGPIOF_BIG_ENDIAN_BYTE_ORDER BIT(3) #endif /* __BASIC_MMIO_GPIO_H */ diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index e0ce311011c0..4d043c30216f 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h @@ -72,7 +72,19 @@ struct bcma_host_ops { /* Core-ID values. */ #define BCMA_CORE_OOB_ROUTER 0x367 /* Out of band */ #define BCMA_CORE_4706_CHIPCOMMON 0x500 +#define BCMA_CORE_PCIEG2 0x501 +#define BCMA_CORE_DMA 0x502 +#define BCMA_CORE_SDIO3 0x503 +#define BCMA_CORE_USB20 0x504 +#define BCMA_CORE_USB30 0x505 +#define BCMA_CORE_A9JTAG 0x506 +#define BCMA_CORE_DDR23 0x507 +#define BCMA_CORE_ROM 0x508 +#define BCMA_CORE_NAND 0x509 +#define BCMA_CORE_QSPI 0x50A +#define BCMA_CORE_CHIPCOMMON_B 0x50B #define BCMA_CORE_4706_SOC_RAM 0x50E +#define BCMA_CORE_ARMCA9 0x510 #define BCMA_CORE_4706_MAC_GBIT 0x52D #define BCMA_CORE_AMEMC 0x52E /* DDR1/2 memory controller core */ #define BCMA_CORE_ALTA 0x534 /* I2S core */ @@ -134,12 +146,17 @@ struct bcma_host_ops { #define BCMA_CORE_I2S 0x834 #define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */ #define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */ +#define BCMA_CORE_PHY_AC 0x83B +#define BCMA_CORE_PCIE2 0x83C /* PCI Express Gen2 */ +#define BCMA_CORE_USB30_DEV 0x83D +#define BCMA_CORE_ARM_CR4 0x83E #define BCMA_CORE_DEFAULT 0xFFF #define BCMA_MAX_NR_CORES 16 /* Chip IDs of PCIe devices */ #define BCMA_CHIP_ID_BCM4313 0x4313 +#define BCMA_CHIP_ID_BCM43142 43142 #define BCMA_CHIP_ID_BCM43224 43224 #define BCMA_PKG_ID_BCM43224_FAB_CSM 0x8 #define BCMA_PKG_ID_BCM43224_FAB_SMIC 0xa @@ -172,6 +189,65 @@ struct bcma_host_ops { #define BCMA_PKG_ID_BCM5357 11 #define BCMA_CHIP_ID_BCM53572 53572 #define BCMA_PKG_ID_BCM47188 9 +#define BCMA_CHIP_ID_BCM4707 53010 +#define BCMA_PKG_ID_BCM4707 1 +#define BCMA_PKG_ID_BCM4708 2 +#define BCMA_PKG_ID_BCM4709 0 +#define BCMA_CHIP_ID_BCM53018 53018 + +/* Board types (on PCI usually equals to the subsystem dev id) */ +/* BCM4313 */ +#define BCMA_BOARD_TYPE_BCM94313BU 0X050F +#define BCMA_BOARD_TYPE_BCM94313HM 0X0510 +#define BCMA_BOARD_TYPE_BCM94313EPA 0X0511 +#define BCMA_BOARD_TYPE_BCM94313HMG 0X051C +/* BCM4716 */ +#define BCMA_BOARD_TYPE_BCM94716NR2 0X04CD +/* BCM43224 */ +#define BCMA_BOARD_TYPE_BCM943224X21 0X056E +#define BCMA_BOARD_TYPE_BCM943224X21_FCC 0X00D1 +#define BCMA_BOARD_TYPE_BCM943224X21B 0X00E9 +#define BCMA_BOARD_TYPE_BCM943224M93 0X008B +#define BCMA_BOARD_TYPE_BCM943224M93A 0X0090 +#define BCMA_BOARD_TYPE_BCM943224X16 0X0093 +#define BCMA_BOARD_TYPE_BCM94322X9 0X008D +#define BCMA_BOARD_TYPE_BCM94322M35E 0X008E +/* BCM43228 */ +#define BCMA_BOARD_TYPE_BCM943228BU8 0X0540 +#define BCMA_BOARD_TYPE_BCM943228BU9 0X0541 +#define BCMA_BOARD_TYPE_BCM943228BU 0X0542 +#define BCMA_BOARD_TYPE_BCM943227HM4L 0X0543 +#define BCMA_BOARD_TYPE_BCM943227HMB 0X0544 +#define BCMA_BOARD_TYPE_BCM943228HM4L 0X0545 +#define BCMA_BOARD_TYPE_BCM943228SD 0X0573 +/* BCM4331 */ +#define BCMA_BOARD_TYPE_BCM94331X19 0X00D6 +#define BCMA_BOARD_TYPE_BCM94331X28 0X00E4 +#define BCMA_BOARD_TYPE_BCM94331X28B 0X010E +#define BCMA_BOARD_TYPE_BCM94331PCIEBT3AX 0X00E4 +#define BCMA_BOARD_TYPE_BCM94331X12_2G 0X00EC +#define BCMA_BOARD_TYPE_BCM94331X12_5G 0X00ED +#define BCMA_BOARD_TYPE_BCM94331X29B 0X00EF +#define BCMA_BOARD_TYPE_BCM94331CSAX 0X00EF +#define BCMA_BOARD_TYPE_BCM94331X19C 0X00F5 +#define BCMA_BOARD_TYPE_BCM94331X33 0X00F4 +#define BCMA_BOARD_TYPE_BCM94331BU 0X0523 +#define BCMA_BOARD_TYPE_BCM94331S9BU 0X0524 +#define BCMA_BOARD_TYPE_BCM94331MC 0X0525 +#define BCMA_BOARD_TYPE_BCM94331MCI 0X0526 +#define BCMA_BOARD_TYPE_BCM94331PCIEBT4 0X0527 +#define BCMA_BOARD_TYPE_BCM94331HM 0X0574 +#define BCMA_BOARD_TYPE_BCM94331PCIEDUAL 0X059B +#define BCMA_BOARD_TYPE_BCM94331MCH5 0X05A9 +#define BCMA_BOARD_TYPE_BCM94331CS 0X05C6 +#define BCMA_BOARD_TYPE_BCM94331CD 0X05DA +/* BCM53572 */ +#define BCMA_BOARD_TYPE_BCM953572BU 0X058D +#define BCMA_BOARD_TYPE_BCM953572NR2 0X058E +#define BCMA_BOARD_TYPE_BCM947188NR2 0X058F +#define BCMA_BOARD_TYPE_BCM953572SDRNR2 0X0590 +/* BCM43142 */ +#define BCMA_BOARD_TYPE_BCM943142HM 0X05E0 struct bcma_device { struct bcma_bus *bus; diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index 8390c474f69a..c49e1a159e6e 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -104,6 +104,7 @@ #define BCMA_CC_CHIPST_4706_MIPS_BENDIAN BIT(3) /* 0: little, 1: big endian */ #define BCMA_CC_CHIPST_4706_PCIE1_DISABLE BIT(5) /* PCIE1 enable strap pin */ #define BCMA_CC_CHIPST_5357_NAND_BOOT BIT(4) /* NAND boot, valid for CC rev 38 and/or BCM5357 */ +#define BCMA_CC_CHIPST_4360_XTAL_40MZ 0x00000001 #define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */ #define BCMA_CC_JCMD_START 0x80000000 #define BCMA_CC_JCMD_BUSY 0x80000000 @@ -315,6 +316,9 @@ #define BCMA_CC_PMU_CTL 0x0600 /* PMU control */ #define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */ #define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16 +#define BCMA_CC_PMU_CTL_RES 0x00006000 /* reset control mask */ +#define BCMA_CC_PMU_CTL_RES_SHIFT 13 +#define BCMA_CC_PMU_CTL_RES_RELOAD 0x2 /* reload POR values */ #define BCMA_CC_PMU_CTL_PLL_UPD 0x00000400 #define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ #define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ @@ -326,6 +330,8 @@ #define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */ #define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */ #define BCMA_CC_PMU_STAT 0x0608 /* PMU status */ +#define BCMA_CC_PMU_STAT_EXT_LPO_AVAIL 0x00000100 +#define BCMA_CC_PMU_STAT_WDRESET 0x00000080 #define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */ #define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */ #define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */ @@ -351,6 +357,11 @@ #define BCMA_CC_REGCTL_DATA 0x065C #define BCMA_CC_PLLCTL_ADDR 0x0660 #define BCMA_CC_PLLCTL_DATA 0x0664 +#define BCMA_CC_PMU_STRAPOPT 0x0668 /* (corerev >= 28) */ +#define BCMA_CC_PMU_XTAL_FREQ 0x066C /* (pmurev >= 10) */ +#define BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK 0x00001FFF +#define BCMA_CC_PMU_XTAL_FREQ_MEASURE_MASK 0x80000000 +#define BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT 31 #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */ /* NAND flash MLC controller registers (corerev >= 38) */ #define BCMA_CC_NAND_REVISION 0x0C00 @@ -431,6 +442,23 @@ #define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007 #define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_SHIFT 0 +/* PMU rev 15 */ +#define BCMA_CC_PMU15_PLL_PLLCTL0 0 +#define BCMA_CC_PMU15_PLL_PC0_CLKSEL_MASK 0x00000003 +#define BCMA_CC_PMU15_PLL_PC0_CLKSEL_SHIFT 0 +#define BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK 0x003FFFFC +#define BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT 2 +#define BCMA_CC_PMU15_PLL_PC0_PRESCALE_MASK 0x00C00000 +#define BCMA_CC_PMU15_PLL_PC0_PRESCALE_SHIFT 22 +#define BCMA_CC_PMU15_PLL_PC0_KPCTRL_MASK 0x07000000 +#define BCMA_CC_PMU15_PLL_PC0_KPCTRL_SHIFT 24 +#define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_MASK 0x38000000 +#define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_SHIFT 27 +#define BCMA_CC_PMU15_PLL_PC0_FDCMODE_MASK 0x40000000 +#define BCMA_CC_PMU15_PLL_PC0_FDCMODE_SHIFT 30 +#define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_MASK 0x80000000 +#define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_SHIFT 31 + /* ALP clock on pre-PMU chips */ #define BCMA_CC_PMU_ALP_CLOCK 20000000 /* HT clock for systems with PMU-enabled chipcommon */ @@ -503,6 +531,37 @@ #define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE BIT(18) #define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE BIT(19) +#define BCMA_RES_4314_LPLDO_PU BIT(0) +#define BCMA_RES_4314_PMU_SLEEP_DIS BIT(1) +#define BCMA_RES_4314_PMU_BG_PU BIT(2) +#define BCMA_RES_4314_CBUCK_LPOM_PU BIT(3) +#define BCMA_RES_4314_CBUCK_PFM_PU BIT(4) +#define BCMA_RES_4314_CLDO_PU BIT(5) +#define BCMA_RES_4314_LPLDO2_LVM BIT(6) +#define BCMA_RES_4314_WL_PMU_PU BIT(7) +#define BCMA_RES_4314_LNLDO_PU BIT(8) +#define BCMA_RES_4314_LDO3P3_PU BIT(9) +#define BCMA_RES_4314_OTP_PU BIT(10) +#define BCMA_RES_4314_XTAL_PU BIT(11) +#define BCMA_RES_4314_WL_PWRSW_PU BIT(12) +#define BCMA_RES_4314_LQ_AVAIL BIT(13) +#define BCMA_RES_4314_LOGIC_RET BIT(14) +#define BCMA_RES_4314_MEM_SLEEP BIT(15) +#define BCMA_RES_4314_MACPHY_RET BIT(16) +#define BCMA_RES_4314_WL_CORE_READY BIT(17) +#define BCMA_RES_4314_ILP_REQ BIT(18) +#define BCMA_RES_4314_ALP_AVAIL BIT(19) +#define BCMA_RES_4314_MISC_PWRSW_PU BIT(20) +#define BCMA_RES_4314_SYNTH_PWRSW_PU BIT(21) +#define BCMA_RES_4314_RX_PWRSW_PU BIT(22) +#define BCMA_RES_4314_RADIO_PU BIT(23) +#define BCMA_RES_4314_VCO_LDO_PU BIT(24) +#define BCMA_RES_4314_AFE_LDO_PU BIT(25) +#define BCMA_RES_4314_RX_LDO_PU BIT(26) +#define BCMA_RES_4314_TX_LDO_PU BIT(27) +#define BCMA_RES_4314_HT_AVAIL BIT(28) +#define BCMA_RES_4314_MACPHY_CLK_AVAIL BIT(29) + /* Data for the PMU, if available. * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) */ @@ -607,6 +666,8 @@ void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks); +extern u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc); + void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value); u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask); diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h index 424760f01b9d..0333e605ea0d 100644 --- a/include/linux/bcma/bcma_driver_pci.h +++ b/include/linux/bcma/bcma_driver_pci.h @@ -181,10 +181,31 @@ struct pci_dev; #define BCMA_CORE_PCI_CFG_DEVCTRL 0xd8 +#define BCMA_CORE_PCI_ + +/* MDIO devices (SERDES modules) */ +#define BCMA_CORE_PCI_MDIO_IEEE0 0x000 +#define BCMA_CORE_PCI_MDIO_IEEE1 0x001 +#define BCMA_CORE_PCI_MDIO_BLK0 0x800 +#define BCMA_CORE_PCI_MDIO_BLK1 0x801 +#define BCMA_CORE_PCI_MDIO_BLK1_MGMT0 0x16 +#define BCMA_CORE_PCI_MDIO_BLK1_MGMT1 0x17 +#define BCMA_CORE_PCI_MDIO_BLK1_MGMT2 0x18 +#define BCMA_CORE_PCI_MDIO_BLK1_MGMT3 0x19 +#define BCMA_CORE_PCI_MDIO_BLK1_MGMT4 0x1A +#define BCMA_CORE_PCI_MDIO_BLK2 0x802 +#define BCMA_CORE_PCI_MDIO_BLK3 0x803 +#define BCMA_CORE_PCI_MDIO_BLK4 0x804 +#define BCMA_CORE_PCI_MDIO_TXPLL 0x808 /* TXPLL register block idx */ +#define BCMA_CORE_PCI_MDIO_TXCTRL0 0x820 +#define BCMA_CORE_PCI_MDIO_SERDESID 0x831 +#define BCMA_CORE_PCI_MDIO_RXCTRL0 0x840 + /* PCIE Root Capability Register bits (Host mode only) */ #define BCMA_CORE_PCI_RC_CRS_VISIBILITY 0x0001 struct bcma_drv_pci; +struct bcma_bus; #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE struct bcma_drv_pci_host { @@ -219,7 +240,9 @@ struct bcma_drv_pci { extern void bcma_core_pci_init(struct bcma_drv_pci *pc); extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, bool enable); -extern void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend); +extern void bcma_core_pci_up(struct bcma_bus *bus); +extern void bcma_core_pci_down(struct bcma_bus *bus); +extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up); extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev); extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev); diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h index 7e8104bb7a7e..917dcd7965e7 100644 --- a/include/linux/bcma/bcma_regs.h +++ b/include/linux/bcma/bcma_regs.h @@ -37,6 +37,7 @@ #define BCMA_IOST_BIST_DONE 0x8000 #define BCMA_RESET_CTL 0x0800 #define BCMA_RESET_CTL_RESET 0x0001 +#define BCMA_RESET_ST 0x0804 /* BCMA PCI config space registers. */ #define BCMA_PCI_PMCSR 0x44 diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index c3a09149f793..e8112ae50531 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -31,7 +31,7 @@ struct linux_binprm { #ifdef __alpha__ unsigned int taso:1; #endif - unsigned int recursion_depth; + unsigned int recursion_depth; /* only for search_binary_handler() */ struct file * file; struct cred *cred; /* new credentials */ int unsafe; /* how unsafe this exec is (mask of LSM_UNSAFE_*) */ @@ -118,5 +118,6 @@ extern int prepare_bprm_creds(struct linux_binprm *bprm); extern void install_exec_creds(struct linux_binprm *bprm); extern void set_binfmt(struct linux_binfmt *new); extern void free_bprm(struct linux_binprm *); +extern ssize_t read_code(struct file *, unsigned long, loff_t, size_t); #endif /* _LINUX_BINFMTS_H */ diff --git a/include/linux/bio.h b/include/linux/bio.h index 820e7aaad4fd..4fd525342596 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -67,6 +67,7 @@ #define bio_offset(bio) bio_iovec((bio))->bv_offset #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) #define bio_sectors(bio) ((bio)->bi_size >> 9) +#define bio_end_sector(bio) ((bio)->bi_sector + bio_sectors((bio))) static inline unsigned int bio_cur_bytes(struct bio *bio) { @@ -84,11 +85,6 @@ static inline void *bio_data(struct bio *bio) return NULL; } -static inline int bio_has_allocated_vec(struct bio *bio) -{ - return bio->bi_io_vec && bio->bi_io_vec != bio->bi_inline_vecs; -} - /* * will die */ @@ -101,11 +97,11 @@ static inline int bio_has_allocated_vec(struct bio *bio) * permanent PIO fall back, user is probably better off disabling highmem * I/O completely on that queue (see ide-dma for example) */ -#define __bio_kmap_atomic(bio, idx, kmtype) \ +#define __bio_kmap_atomic(bio, idx) \ (kmap_atomic(bio_iovec_idx((bio), (idx))->bv_page) + \ bio_iovec_idx((bio), (idx))->bv_offset) -#define __bio_kunmap_atomic(addr, kmtype) kunmap_atomic(addr) +#define __bio_kunmap_atomic(addr) kunmap_atomic(addr) /* * merge helpers etc @@ -136,16 +132,27 @@ static inline int bio_has_allocated_vec(struct bio *bio) #define bio_io_error(bio) bio_endio((bio), -EIO) /* - * drivers should not use the __ version unless they _really_ want to - * run through the entire bio and not just pending pieces + * drivers should not use the __ version unless they _really_ know what + * they're doing */ #define __bio_for_each_segment(bvl, bio, i, start_idx) \ for (bvl = bio_iovec_idx((bio), (start_idx)), i = (start_idx); \ i < (bio)->bi_vcnt; \ bvl++, i++) +/* + * drivers should _never_ use the all version - the bio may have been split + * before it got to the driver and the driver won't own all of it + */ +#define bio_for_each_segment_all(bvl, bio, i) \ + for (i = 0; \ + bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt; \ + i++) + #define bio_for_each_segment(bvl, bio, i) \ - __bio_for_each_segment(bvl, bio, i, (bio)->bi_idx) + for (i = (bio)->bi_idx; \ + bvl = bio_iovec_idx((bio), (i)), i < (bio)->bi_vcnt; \ + i++) /* * get a reference to a bio, so it won't disappear. the intended use is @@ -180,9 +187,12 @@ struct bio_integrity_payload { unsigned short bip_slab; /* slab the bip came from */ unsigned short bip_vcnt; /* # of integrity bio_vecs */ unsigned short bip_idx; /* current bip_vec index */ + unsigned bip_owns_buf:1; /* should free bip_buf */ struct work_struct bip_work; /* I/O completion */ - struct bio_vec bip_vec[0]; /* embedded bvec array */ + + struct bio_vec *bip_vec; + struct bio_vec bip_inline_vecs[0];/* embedded bvec array */ }; #endif /* CONFIG_BLK_DEV_INTEGRITY */ @@ -211,6 +221,7 @@ extern void bio_pair_release(struct bio_pair *dbio); extern struct bio_set *bioset_create(unsigned int, unsigned int); extern void bioset_free(struct bio_set *); +extern mempool_t *biovec_create_pool(struct bio_set *bs, int pool_entries); extern struct bio *bio_alloc_bioset(gfp_t, int, struct bio_set *); extern void bio_put(struct bio *); @@ -245,6 +256,9 @@ extern void bio_endio(struct bio *, int); struct request_queue; extern int bio_phys_segments(struct request_queue *, struct bio *); +extern int submit_bio_wait(int rw, struct bio *bio); +extern void bio_advance(struct bio *, unsigned); + extern void bio_init(struct bio *); extern void bio_reset(struct bio *); @@ -279,6 +293,9 @@ static inline void bio_flush_dcache_pages(struct bio *bi) } #endif +extern void bio_copy_data(struct bio *dst, struct bio *src); +extern int bio_alloc_pages(struct bio *bio, gfp_t gfp); + extern struct bio *bio_copy_user(struct request_queue *, struct rq_map_data *, unsigned long, unsigned int, int, gfp_t); extern struct bio *bio_copy_user_iov(struct request_queue *, @@ -286,10 +303,18 @@ extern struct bio *bio_copy_user_iov(struct request_queue *, int, int, gfp_t); extern int bio_uncopy_user(struct bio *); void zero_fill_bio(struct bio *bio); -extern struct bio_vec *bvec_alloc_bs(gfp_t, int, unsigned long *, struct bio_set *); -extern void bvec_free_bs(struct bio_set *, struct bio_vec *, unsigned int); +extern struct bio_vec *bvec_alloc(gfp_t, int, unsigned long *, mempool_t *); +extern void bvec_free(mempool_t *, struct bio_vec *, unsigned int); extern unsigned int bvec_nr_vecs(unsigned short idx); +static inline ssize_t bvec_length(const struct bio_vec *bvec, unsigned long nr) +{ + ssize_t bytes = 0; + while (nr--) + bytes += (bvec++)->bv_len; + return bytes; +} + #ifdef CONFIG_BLK_CGROUP int bio_associate_current(struct bio *bio); void bio_disassociate_task(struct bio *bio); @@ -298,39 +323,6 @@ static inline int bio_associate_current(struct bio *bio) { return -ENOENT; } static inline void bio_disassociate_task(struct bio *bio) { } #endif /* CONFIG_BLK_CGROUP */ -/* - * bio_set is used to allow other portions of the IO system to - * allocate their own private memory pools for bio and iovec structures. - * These memory pools in turn all allocate from the bio_slab - * and the bvec_slabs[]. - */ -#define BIO_POOL_SIZE 2 -#define BIOVEC_NR_POOLS 6 -#define BIOVEC_MAX_IDX (BIOVEC_NR_POOLS - 1) - -struct bio_set { - struct kmem_cache *bio_slab; - unsigned int front_pad; - - mempool_t *bio_pool; -#if defined(CONFIG_BLK_DEV_INTEGRITY) - mempool_t *bio_integrity_pool; -#endif - mempool_t *bvec_pool; -}; - -struct biovec_slab { - int nr_vecs; - char *name; - struct kmem_cache *slab; -}; - -/* - * a small number of entries is fine, not going to be performance critical. - * basically we just need to survive - */ -#define BIO_SPLIT_ENTRIES 2 - #ifdef CONFIG_HIGHMEM /* * remember never ever reenable interrupts between a bvec_kmap_irq and @@ -527,6 +519,49 @@ static inline struct bio *bio_list_get(struct bio_list *bl) return bio; } +/* + * bio_set is used to allow other portions of the IO system to + * allocate their own private memory pools for bio and iovec structures. + * These memory pools in turn all allocate from the bio_slab + * and the bvec_slabs[]. + */ +#define BIO_POOL_SIZE 2 +#define BIOVEC_NR_POOLS 6 +#define BIOVEC_MAX_IDX (BIOVEC_NR_POOLS - 1) + +struct bio_set { + struct kmem_cache *bio_slab; + unsigned int front_pad; + + mempool_t *bio_pool; + mempool_t *bvec_pool; +#if defined(CONFIG_BLK_DEV_INTEGRITY) + mempool_t *bio_integrity_pool; + mempool_t *bvec_integrity_pool; +#endif + + /* + * Deadlock avoidance for stacking block drivers: see comments in + * bio_alloc_bioset() for details + */ + spinlock_t rescue_lock; + struct bio_list rescue_list; + struct work_struct rescue_work; + struct workqueue_struct *rescue_workqueue; +}; + +struct biovec_slab { + int nr_vecs; + char *name; + struct kmem_cache *slab; +}; + +/* + * a small number of entries is fine, not going to be performance critical. + * basically we just need to survive + */ +#define BIO_SPLIT_ENTRIES 2 + #if defined(CONFIG_BLK_DEV_INTEGRITY) #define bip_vec_idx(bip, idx) (&(bip->bip_vec[(idx)])) diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index cdf11191e645..1bea25f14796 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -111,12 +111,14 @@ struct bio { #define BIO_FS_INTEGRITY 9 /* fs owns integrity data, not block layer */ #define BIO_QUIET 10 /* Make BIO Quiet */ #define BIO_MAPPED_INTEGRITY 11/* integrity metadata has been remapped */ +#define BIO_SNAP_STABLE 12 /* bio data must be snapshotted during write */ /* * Flags starting here get preserved by bio_reset() - this includes * BIO_POOL_IDX() */ -#define BIO_RESET_BITS 12 +#define BIO_RESET_BITS 13 +#define BIO_OWNS_VEC 13 /* bio_free() should free bvec */ #define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag))) @@ -174,7 +176,7 @@ enum rq_flag_bits { __REQ_FLUSH_SEQ, /* request for flush sequence */ __REQ_IO_STAT, /* account I/O stat */ __REQ_MIXED_MERGE, /* merge of different types, fail separately */ - __REQ_KERNEL, /* direct IO to kernel pages */ + __REQ_PM, /* runtime pm request */ __REQ_NR_BITS, /* stops here */ }; @@ -197,6 +199,8 @@ enum rq_flag_bits { REQ_SECURE) #define REQ_CLONE_MASK REQ_COMMON_MASK +#define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME) + /* This mask is used for both bio and request merge checking */ #define REQ_NOMERGE_FLAGS \ (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA) @@ -222,6 +226,6 @@ enum rq_flag_bits { #define REQ_IO_STAT (1 << __REQ_IO_STAT) #define REQ_MIXED_MERGE (1 << __REQ_MIXED_MERGE) #define REQ_SECURE (1 << __REQ_SECURE) -#define REQ_KERNEL (1 << __REQ_KERNEL) +#define REQ_PM (1 << __REQ_PM) #endif /* __LINUX_BLK_TYPES_H */ diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 78feda9bbae2..0e6f765aa1f5 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -361,6 +361,12 @@ struct request_queue { */ struct kobject kobj; +#ifdef CONFIG_PM_RUNTIME + struct device *dev; + int rpm_status; + unsigned int nr_pending; +#endif + /* * queue settings */ @@ -838,7 +844,7 @@ static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q, unsigned int cmd_flags) { if (unlikely(cmd_flags & REQ_DISCARD)) - return q->limits.max_discard_sectors; + return min(q->limits.max_discard_sectors, UINT_MAX >> 9); if (unlikely(cmd_flags & REQ_WRITE_SAME)) return q->limits.max_write_same_sectors; @@ -856,6 +862,17 @@ static inline unsigned int blk_rq_get_max_sectors(struct request *rq) return blk_queue_get_max_sectors(q, rq->cmd_flags); } +static inline unsigned int blk_rq_count_bios(struct request *rq) +{ + unsigned int nr_bios = 0; + struct bio *bio; + + __rq_for_each_bio(bio, rq) + nr_bios++; + + return nr_bios; +} + /* * Request issue related functions. */ @@ -961,6 +978,27 @@ struct request_queue *blk_alloc_queue_node(gfp_t, int); extern void blk_put_queue(struct request_queue *); /* + * block layer runtime pm functions + */ +#ifdef CONFIG_PM_RUNTIME +extern void blk_pm_runtime_init(struct request_queue *q, struct device *dev); +extern int blk_pre_runtime_suspend(struct request_queue *q); +extern void blk_post_runtime_suspend(struct request_queue *q, int err); +extern void blk_pre_runtime_resume(struct request_queue *q); +extern void blk_post_runtime_resume(struct request_queue *q, int err); +#else +static inline void blk_pm_runtime_init(struct request_queue *q, + struct device *dev) {} +static inline int blk_pre_runtime_suspend(struct request_queue *q) +{ + return -ENOSYS; +} +static inline void blk_post_runtime_suspend(struct request_queue *q, int err) {} +static inline void blk_pre_runtime_resume(struct request_queue *q) {} +static inline void blk_post_runtime_resume(struct request_queue *q, int err) {} +#endif + +/* * blk_plug permits building a queue of related requests by holding the I/O * fragments for a short period. This allows merging of sequential requests * into single larger request. As the requests are moved from a per-task list to @@ -1484,7 +1522,7 @@ static inline bool blk_integrity_is_initialized(struct gendisk *g) struct block_device_operations { int (*open) (struct block_device *, fmode_t); - int (*release) (struct gendisk *, fmode_t); + void (*release) (struct gendisk *, fmode_t); int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); int (*direct_access) (struct block_device *, sector_t, diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 0ea61e07a91c..7c2e030e72f1 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -12,7 +12,6 @@ struct blk_trace { int trace_state; - bool rq_based; struct rchan *rchan; unsigned long __percpu *sequence; unsigned char __percpu *msg_data; diff --git a/include/linux/blockconsole.h b/include/linux/blockconsole.h new file mode 100644 index 000000000000..114f7c50d333 --- /dev/null +++ b/include/linux/blockconsole.h @@ -0,0 +1,7 @@ +#ifndef LINUX_BLOCKCONSOLE_H +#define LINUX_BLOCKCONSOLE_H + +int bcon_magic_present(const void *data); +void bcon_add(const char *name); + +#endif diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index cdc3bab01832..f1f07d31a3af 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h @@ -44,9 +44,8 @@ extern unsigned long init_bootmem_node(pg_data_t *pgdat, unsigned long endpfn); extern unsigned long init_bootmem(unsigned long addr, unsigned long memend); -extern unsigned long free_low_memory_core_early(int nodeid); -extern unsigned long free_all_bootmem_node(pg_data_t *pgdat); extern unsigned long free_all_bootmem(void); +extern void reset_all_zones_managed_pages(void); extern void free_bootmem_node(pg_data_t *pgdat, unsigned long addr, diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index b840a4960282..677b4f01b2d0 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h @@ -1,3 +1,6 @@ +#ifndef _LINUX_BRCMPHY_H +#define _LINUX_BRCMPHY_H + #define PHY_ID_BCM50610 0x0143bd60 #define PHY_ID_BCM50610M 0x0143bd70 #define PHY_ID_BCM5241 0x0143bc30 @@ -29,3 +32,5 @@ #define PHY_BRCM_CLEAR_RGMII_MODE 0x00004000 #define PHY_BRCM_DIS_TXCRXC_NOENRGY 0x00008000 #define PHY_BCM_FLAGS_VALID 0x80000000 + +#endif /* _LINUX_BRCMPHY_H */ diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 5afc4f94d110..d77797a52b7b 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -34,6 +34,9 @@ enum bh_state_bits { BH_Write_EIO, /* I/O error on write */ BH_Unwritten, /* Buffer is allocated on disk but not written */ BH_Quiet, /* Buffer Error Prinks to be quiet */ + BH_Meta, /* Buffer contains metadata */ + BH_Prio, /* Buffer should be submitted with REQ_PRIO */ + BH_Defer_Completion, /* Defer AIO completion to workqueue */ BH_PrivateStart,/* not a state bit, but the first bit available * for private allocation by other entities @@ -124,6 +127,9 @@ BUFFER_FNS(Delay, delay) BUFFER_FNS(Boundary, boundary) BUFFER_FNS(Write_EIO, write_io_error) BUFFER_FNS(Unwritten, unwritten) +BUFFER_FNS(Meta, meta) +BUFFER_FNS(Prio, prio) +BUFFER_FNS(Defer_Completion, defer_completion) #define bh_offset(bh) ((unsigned long)(bh)->b_data & ~PAGE_MASK) @@ -135,6 +141,9 @@ BUFFER_FNS(Unwritten, unwritten) }) #define page_has_buffers(page) PagePrivate(page) +void buffer_check_dirty_writeback(struct page *page, + bool *dirty, bool *writeback); + /* * Declarations */ @@ -181,6 +190,7 @@ void ll_rw_block(int, int, struct buffer_head * bh[]); int sync_dirty_buffer(struct buffer_head *bh); int __sync_dirty_buffer(struct buffer_head *bh, int rw); void write_dirty_buffer(struct buffer_head *bh, int rw); +int _submit_bh(int rw, struct buffer_head *bh, unsigned long bio_flags); int submit_bh(int, struct buffer_head *); void write_boundary_block(struct block_device *bdev, sector_t bblock, unsigned blocksize); @@ -193,7 +203,8 @@ extern int buffer_heads_over_limit; * Generic address_space_operations implementations for buffer_head-backed * address_spaces. */ -void block_invalidatepage(struct page *page, unsigned long offset); +void block_invalidatepage(struct page *page, unsigned int offset, + unsigned int length); int block_write_full_page(struct page *page, get_block_t *get_block, struct writeback_control *wbc); int block_write_full_page_endio(struct page *page, get_block_t *get_block, diff --git a/include/linux/can/platform/flexcan.h b/include/linux/can/platform/flexcan.h deleted file mode 100644 index 72b713ab57e9..000000000000 --- a/include/linux/can/platform/flexcan.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2010 Marc Kleine-Budde <kernel@pengutronix.de> - * - * This file is released under the GPLv2 - * - */ - -#ifndef __CAN_PLATFORM_FLEXCAN_H -#define __CAN_PLATFORM_FLEXCAN_H - -/** - * struct flexcan_platform_data - flex CAN controller platform data - * @transceiver_enable: - called to power on/off the transceiver - * - */ -struct flexcan_platform_data { - void (*transceiver_switch)(int enable); -}; - -#endif /* __CAN_PLATFORM_FLEXCAN_H */ diff --git a/include/linux/can/platform/mcp251x.h b/include/linux/can/platform/mcp251x.h index 089fe43211a4..dc029dba7a03 100644 --- a/include/linux/can/platform/mcp251x.h +++ b/include/linux/can/platform/mcp251x.h @@ -9,26 +9,13 @@ #include <linux/spi/spi.h> -/** +/* * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data * @oscillator_frequency: - oscillator frequency in Hz - * @irq_flags: - IRQF configuration flags - * @board_specific_setup: - called before probing the chip (power,reset) - * @transceiver_enable: - called to power on/off the transceiver - * @power_enable: - called to power on/off the mcp *and* the - * transceiver - * - * Please note that you should define power_enable or transceiver_enable or - * none of them. Defining both of them is no use. - * */ struct mcp251x_platform_data { unsigned long oscillator_frequency; - unsigned long irq_flags; - int (*board_specific_setup)(struct spi_device *spi); - int (*transceiver_enable)(int enable); - int (*power_enable) (int enable); }; #endif /* __CAN_PLATFORM_MCP251X_H__ */ diff --git a/include/linux/capability.h b/include/linux/capability.h index 98503b792369..a6ee1f9a5018 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -35,6 +35,7 @@ struct cpu_vfs_cap_data { #define _KERNEL_CAP_T_SIZE (sizeof(kernel_cap_t)) +struct file; struct inode; struct dentry; struct user_namespace; @@ -209,8 +210,8 @@ extern bool has_ns_capability_noaudit(struct task_struct *t, struct user_namespace *ns, int cap); extern bool capable(int cap); extern bool ns_capable(struct user_namespace *ns, int cap); -extern bool nsown_capable(int cap); extern bool inode_capable(const struct inode *inode, int cap); +extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); /* audit system wants to get cap info from files as well */ extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h index d4080f309b56..5f3386844134 100644 --- a/include/linux/ceph/auth.h +++ b/include/linux/ceph/auth.h @@ -52,6 +52,9 @@ struct ceph_auth_client_ops { */ int (*create_authorizer)(struct ceph_auth_client *ac, int peer_type, struct ceph_auth_handshake *auth); + /* ensure that an existing authorizer is up to date */ + int (*update_authorizer)(struct ceph_auth_client *ac, int peer_type, + struct ceph_auth_handshake *auth); int (*verify_authorizer_reply)(struct ceph_auth_client *ac, struct ceph_authorizer *a, size_t len); void (*destroy_authorizer)(struct ceph_auth_client *ac, @@ -75,6 +78,8 @@ struct ceph_auth_client { u64 global_id; /* our unique id in system */ const struct ceph_crypto_key *key; /* our secret key */ unsigned want_keys; /* which services we want */ + + struct mutex mutex; }; extern struct ceph_auth_client *ceph_auth_init(const char *name, @@ -94,5 +99,18 @@ extern int ceph_build_auth(struct ceph_auth_client *ac, void *msg_buf, size_t msg_len); extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac); +extern int ceph_auth_create_authorizer(struct ceph_auth_client *ac, + int peer_type, + struct ceph_auth_handshake *auth); +extern void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac, + struct ceph_authorizer *a); +extern int ceph_auth_update_authorizer(struct ceph_auth_client *ac, + int peer_type, + struct ceph_auth_handshake *a); +extern int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac, + struct ceph_authorizer *a, + size_t len); +extern void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, + int peer_type); #endif diff --git a/include/linux/ceph/ceph_features.h b/include/linux/ceph/ceph_features.h index 76554cecaab2..4c42080347af 100644 --- a/include/linux/ceph/ceph_features.h +++ b/include/linux/ceph/ceph_features.h @@ -41,6 +41,7 @@ */ #define CEPH_FEATURES_SUPPORTED_DEFAULT \ (CEPH_FEATURE_NOSRCADDR | \ + CEPH_FEATURE_RECONNECT_SEQ | \ CEPH_FEATURE_PGID64 | \ CEPH_FEATURE_PGPOOL3 | \ CEPH_FEATURE_OSDENC | \ @@ -51,6 +52,7 @@ #define CEPH_FEATURES_REQUIRED_DEFAULT \ (CEPH_FEATURE_NOSRCADDR | \ + CEPH_FEATURE_RECONNECT_SEQ | \ CEPH_FEATURE_PGID64 | \ CEPH_FEATURE_PGPOOL3 | \ CEPH_FEATURE_OSDENC) diff --git a/include/linux/ceph/decode.h b/include/linux/ceph/decode.h index 360d9d08ca9e..0442c3d800f0 100644 --- a/include/linux/ceph/decode.h +++ b/include/linux/ceph/decode.h @@ -8,6 +8,23 @@ #include <linux/ceph/types.h> +/* This seemed to be the easiest place to define these */ + +#define U8_MAX ((u8)(~0U)) +#define U16_MAX ((u16)(~0U)) +#define U32_MAX ((u32)(~0U)) +#define U64_MAX ((u64)(~0ULL)) + +#define S8_MAX ((s8)(U8_MAX >> 1)) +#define S16_MAX ((s16)(U16_MAX >> 1)) +#define S32_MAX ((s32)(U32_MAX >> 1)) +#define S64_MAX ((s64)(U64_MAX >> 1LL)) + +#define S8_MIN ((s8)(-S8_MAX - 1)) +#define S16_MIN ((s16)(-S16_MAX - 1)) +#define S32_MIN ((s32)(-S32_MAX - 1)) +#define S64_MIN ((s64)(-S64_MAX - 1LL)) + /* * in all cases, * void **p pointer to position pointer @@ -137,14 +154,14 @@ bad: static inline void ceph_decode_timespec(struct timespec *ts, const struct ceph_timespec *tv) { - ts->tv_sec = le32_to_cpu(tv->tv_sec); - ts->tv_nsec = le32_to_cpu(tv->tv_nsec); + ts->tv_sec = (__kernel_time_t)le32_to_cpu(tv->tv_sec); + ts->tv_nsec = (long)le32_to_cpu(tv->tv_nsec); } static inline void ceph_encode_timespec(struct ceph_timespec *tv, const struct timespec *ts) { - tv->tv_sec = cpu_to_le32(ts->tv_sec); - tv->tv_nsec = cpu_to_le32(ts->tv_nsec); + tv->tv_sec = cpu_to_le32((u32)ts->tv_sec); + tv->tv_nsec = cpu_to_le32((u32)ts->tv_nsec); } /* diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 29818fc3fa49..2e3024881a5e 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h @@ -66,6 +66,7 @@ struct ceph_options { #define CEPH_OSD_IDLE_TTL_DEFAULT 60 #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024) +#define CEPH_MSG_MAX_MIDDLE_LEN (16*1024*1024) #define CEPH_MSG_MAX_DATA_LEN (16*1024*1024) #define CEPH_AUTH_NAME_DEFAULT "guest" @@ -156,31 +157,11 @@ struct ceph_snap_context { u64 snaps[]; }; -static inline struct ceph_snap_context * -ceph_get_snap_context(struct ceph_snap_context *sc) -{ - /* - printk("get_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref), - atomic_read(&sc->nref)+1); - */ - if (sc) - atomic_inc(&sc->nref); - return sc; -} - -static inline void ceph_put_snap_context(struct ceph_snap_context *sc) -{ - if (!sc) - return; - /* - printk("put_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref), - atomic_read(&sc->nref)-1); - */ - if (atomic_dec_and_test(&sc->nref)) { - /*printk(" deleting snap_context %p\n", sc);*/ - kfree(sc); - } -} +extern struct ceph_snap_context *ceph_create_snap_context(u32 snap_count, + gfp_t gfp_flags); +extern struct ceph_snap_context *ceph_get_snap_context( + struct ceph_snap_context *sc); +extern void ceph_put_snap_context(struct ceph_snap_context *sc); /* * calculate the number of pages a given length and offset map onto, diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h index 60903e0f665c..7c1420bb1dce 100644 --- a/include/linux/ceph/messenger.h +++ b/include/linux/ceph/messenger.h @@ -64,6 +64,77 @@ struct ceph_messenger { u32 required_features; }; +enum ceph_msg_data_type { + CEPH_MSG_DATA_NONE, /* message contains no data payload */ + CEPH_MSG_DATA_PAGES, /* data source/destination is a page array */ + CEPH_MSG_DATA_PAGELIST, /* data source/destination is a pagelist */ +#ifdef CONFIG_BLOCK + CEPH_MSG_DATA_BIO, /* data source/destination is a bio list */ +#endif /* CONFIG_BLOCK */ +}; + +static __inline__ bool ceph_msg_data_type_valid(enum ceph_msg_data_type type) +{ + switch (type) { + case CEPH_MSG_DATA_NONE: + case CEPH_MSG_DATA_PAGES: + case CEPH_MSG_DATA_PAGELIST: +#ifdef CONFIG_BLOCK + case CEPH_MSG_DATA_BIO: +#endif /* CONFIG_BLOCK */ + return true; + default: + return false; + } +} + +struct ceph_msg_data { + struct list_head links; /* ceph_msg->data */ + enum ceph_msg_data_type type; + union { +#ifdef CONFIG_BLOCK + struct { + struct bio *bio; + size_t bio_length; + }; +#endif /* CONFIG_BLOCK */ + struct { + struct page **pages; /* NOT OWNER. */ + size_t length; /* total # bytes */ + unsigned int alignment; /* first page */ + }; + struct ceph_pagelist *pagelist; + }; +}; + +struct ceph_msg_data_cursor { + size_t total_resid; /* across all data items */ + struct list_head *data_head; /* = &ceph_msg->data */ + + struct ceph_msg_data *data; /* current data item */ + size_t resid; /* bytes not yet consumed */ + bool last_piece; /* current is last piece */ + bool need_crc; /* crc update needed */ + union { +#ifdef CONFIG_BLOCK + struct { /* bio */ + struct bio *bio; /* bio from list */ + unsigned int vector_index; /* vector from bio */ + unsigned int vector_offset; /* bytes from vector */ + }; +#endif /* CONFIG_BLOCK */ + struct { /* pages */ + unsigned int page_offset; /* offset in page */ + unsigned short page_index; /* index in array */ + unsigned short page_count; /* pages in array */ + }; + struct { /* pagelist */ + struct page *page; /* page from list */ + size_t offset; /* bytes from list */ + }; + }; +}; + /* * a single message. it contains a header (src, dest, message type, etc.), * footer (crc values, mainly), a "front" message body, and possibly a @@ -74,21 +145,15 @@ struct ceph_msg { struct ceph_msg_footer footer; /* footer */ struct kvec front; /* unaligned blobs of message */ struct ceph_buffer *middle; - struct page **pages; /* data payload. NOT OWNER. */ - unsigned nr_pages; /* size of page array */ - unsigned page_alignment; /* io offset in first page */ - struct ceph_pagelist *pagelist; /* instead of pages */ + + size_t data_length; + struct list_head data; + struct ceph_msg_data_cursor cursor; struct ceph_connection *con; - struct list_head list_head; + struct list_head list_head; /* links for connection lists */ struct kref kref; -#ifdef CONFIG_BLOCK - struct bio *bio; /* instead of pages/pagelist */ - struct bio *bio_iter; /* bio iterator */ - int bio_seg; /* current bio segment */ -#endif /* CONFIG_BLOCK */ - struct ceph_pagelist *trail; /* the trailing part of the data */ bool front_is_vmalloc; bool more_to_follow; bool needs_out_seq; @@ -98,12 +163,6 @@ struct ceph_msg { struct ceph_msgpool *pool; }; -struct ceph_msg_pos { - int page, page_pos; /* which page; offset in page */ - int data_pos; /* offset in data payload */ - bool did_page_crc; /* true if we've calculated crc for current page */ -}; - /* ceph connection fault delay defaults, for exponential backoff */ #define BASE_DELAY_INTERVAL (HZ/2) #define MAX_DELAY_INTERVAL (5 * 60 * HZ) @@ -161,7 +220,6 @@ struct ceph_connection { struct ceph_msg *out_msg; /* sending message (== tail of out_sent) */ bool out_msg_done; - struct ceph_msg_pos out_msg_pos; struct kvec out_kvec[8], /* sending header/footer data */ *out_kvec_cur; @@ -175,7 +233,6 @@ struct ceph_connection { /* message in temps */ struct ceph_msg_header in_hdr; struct ceph_msg *in_msg; - struct ceph_msg_pos in_msg_pos; u32 in_front_crc, in_middle_crc, in_data_crc; /* calculated crc */ char in_tag; /* protocol control byte */ @@ -218,6 +275,15 @@ extern void ceph_msg_revoke_incoming(struct ceph_msg *msg); extern void ceph_con_keepalive(struct ceph_connection *con); +extern void ceph_msg_data_add_pages(struct ceph_msg *msg, struct page **pages, + size_t length, size_t alignment); +extern void ceph_msg_data_add_pagelist(struct ceph_msg *msg, + struct ceph_pagelist *pagelist); +#ifdef CONFIG_BLOCK +extern void ceph_msg_data_add_bio(struct ceph_msg *msg, struct bio *bio, + size_t length); +#endif /* CONFIG_BLOCK */ + extern struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags, bool can_fail); extern void ceph_msg_kfree(struct ceph_msg *m); diff --git a/include/linux/ceph/msgr.h b/include/linux/ceph/msgr.h index 680d3d648cac..3d94a73b5f30 100644 --- a/include/linux/ceph/msgr.h +++ b/include/linux/ceph/msgr.h @@ -87,6 +87,7 @@ struct ceph_entity_inst { #define CEPH_MSGR_TAG_BADPROTOVER 10 /* bad protocol version */ #define CEPH_MSGR_TAG_BADAUTHORIZER 11 /* bad authorizer */ #define CEPH_MSGR_TAG_FEATURES 12 /* insufficient features */ +#define CEPH_MSGR_TAG_SEQ 13 /* 64-bit int follows with seen seq number */ /* diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index 1dd5d466b6f9..8f47625a0661 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h @@ -29,6 +29,7 @@ struct ceph_authorizer; */ typedef void (*ceph_osdc_callback_t)(struct ceph_osd_request *, struct ceph_msg *); +typedef void (*ceph_osdc_unsafe_callback_t)(struct ceph_osd_request *, bool); /* a given osd we're communicating with */ struct ceph_osd { @@ -48,7 +49,67 @@ struct ceph_osd { }; -#define CEPH_OSD_MAX_OP 10 +#define CEPH_OSD_MAX_OP 2 + +enum ceph_osd_data_type { + CEPH_OSD_DATA_TYPE_NONE = 0, + CEPH_OSD_DATA_TYPE_PAGES, + CEPH_OSD_DATA_TYPE_PAGELIST, +#ifdef CONFIG_BLOCK + CEPH_OSD_DATA_TYPE_BIO, +#endif /* CONFIG_BLOCK */ +}; + +struct ceph_osd_data { + enum ceph_osd_data_type type; + union { + struct { + struct page **pages; + u64 length; + u32 alignment; + bool pages_from_pool; + bool own_pages; + }; + struct ceph_pagelist *pagelist; +#ifdef CONFIG_BLOCK + struct { + struct bio *bio; /* list of bios */ + size_t bio_length; /* total in list */ + }; +#endif /* CONFIG_BLOCK */ + }; +}; + +struct ceph_osd_req_op { + u16 op; /* CEPH_OSD_OP_* */ + u32 payload_len; + union { + struct ceph_osd_data raw_data_in; + struct { + u64 offset, length; + u64 truncate_size; + u32 truncate_seq; + struct ceph_osd_data osd_data; + } extent; + struct { + const char *class_name; + const char *method_name; + struct ceph_osd_data request_info; + struct ceph_osd_data request_data; + struct ceph_osd_data response_data; + __u8 class_len; + __u8 method_len; + __u8 argc; + } cls; + struct { + u64 cookie; + u64 ver; + u32 prot_ver; + u32 timeout; + __u8 flag; + } watch; + }; +}; /* an in-flight request */ struct ceph_osd_request { @@ -63,15 +124,14 @@ struct ceph_osd_request { int r_pg_osds[CEPH_PG_MAX_SIZE]; int r_num_pg_osds; - struct ceph_connection *r_con_filling_msg; - struct ceph_msg *r_request, *r_reply; int r_flags; /* any additional flags for the osd */ u32 r_sent; /* >0 if r_request is sending/sent */ - int r_num_ops; - /* encoded message content */ - struct ceph_osd_op *r_request_ops; + /* request osd ops array */ + unsigned int r_num_ops; + struct ceph_osd_req_op r_ops[CEPH_OSD_MAX_OP]; + /* these are updated on each send */ __le32 *r_request_osdmap_epoch; __le32 *r_request_flags; @@ -90,7 +150,8 @@ struct ceph_osd_request { struct kref r_kref; bool r_mempool; struct completion r_completion, r_safe_completion; - ceph_osdc_callback_t r_callback, r_safe_callback; + ceph_osdc_callback_t r_callback; + ceph_osdc_unsafe_callback_t r_unsafe_callback; struct ceph_eversion r_reassert_version; struct list_head r_unsafe_item; @@ -104,16 +165,6 @@ struct ceph_osd_request { struct ceph_file_layout r_file_layout; struct ceph_snap_context *r_snapc; /* snap context for writes */ - unsigned r_num_pages; /* size of page array (follows) */ - unsigned r_page_alignment; /* io offset in first page */ - struct page **r_pages; /* pages for data payload */ - int r_pages_from_pool; - int r_own_pages; /* if true, i own page list */ -#ifdef CONFIG_BLOCK - struct bio *r_bio; /* instead of pages */ -#endif - - struct ceph_pagelist r_trail; /* trailing part of the data */ }; struct ceph_osd_event { @@ -172,48 +223,8 @@ struct ceph_osd_client { struct workqueue_struct *notify_wq; }; -struct ceph_osd_req_op { - u16 op; /* CEPH_OSD_OP_* */ - u32 payload_len; - union { - struct { - u64 offset, length; - u64 truncate_size; - u32 truncate_seq; - } extent; - struct { - const char *name; - const char *val; - u32 name_len; - u32 value_len; - __u8 cmp_op; /* CEPH_OSD_CMPXATTR_OP_* */ - __u8 cmp_mode; /* CEPH_OSD_CMPXATTR_MODE_* */ - } xattr; - struct { - const char *class_name; - const char *method_name; - const char *indata; - u32 indata_len; - __u8 class_len; - __u8 method_len; - __u8 argc; - } cls; - struct { - u64 cookie; - u64 count; - } pgls; - struct { - u64 snapid; - } snap; - struct { - u64 cookie; - u64 ver; - u32 prot_ver; - u32 timeout; - __u8 flag; - } watch; - }; -}; +extern int ceph_osdc_setup(void); +extern void ceph_osdc_cleanup(void); extern int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client); @@ -224,16 +235,71 @@ extern void ceph_osdc_handle_reply(struct ceph_osd_client *osdc, extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg); +extern void osd_req_op_init(struct ceph_osd_request *osd_req, + unsigned int which, u16 opcode); + +extern void osd_req_op_raw_data_in_pages(struct ceph_osd_request *, + unsigned int which, + struct page **pages, u64 length, + u32 alignment, bool pages_from_pool, + bool own_pages); + +extern void osd_req_op_extent_init(struct ceph_osd_request *osd_req, + unsigned int which, u16 opcode, + u64 offset, u64 length, + u64 truncate_size, u32 truncate_seq); +extern void osd_req_op_extent_update(struct ceph_osd_request *osd_req, + unsigned int which, u64 length); + +extern struct ceph_osd_data *osd_req_op_extent_osd_data( + struct ceph_osd_request *osd_req, + unsigned int which); +extern struct ceph_osd_data *osd_req_op_cls_response_data( + struct ceph_osd_request *osd_req, + unsigned int which); + +extern void osd_req_op_extent_osd_data_pages(struct ceph_osd_request *, + unsigned int which, + struct page **pages, u64 length, + u32 alignment, bool pages_from_pool, + bool own_pages); +extern void osd_req_op_extent_osd_data_pagelist(struct ceph_osd_request *, + unsigned int which, + struct ceph_pagelist *pagelist); +#ifdef CONFIG_BLOCK +extern void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *, + unsigned int which, + struct bio *bio, size_t bio_length); +#endif /* CONFIG_BLOCK */ + +extern void osd_req_op_cls_request_data_pagelist(struct ceph_osd_request *, + unsigned int which, + struct ceph_pagelist *pagelist); +extern void osd_req_op_cls_request_data_pages(struct ceph_osd_request *, + unsigned int which, + struct page **pages, u64 length, + u32 alignment, bool pages_from_pool, + bool own_pages); +extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *, + unsigned int which, + struct page **pages, u64 length, + u32 alignment, bool pages_from_pool, + bool own_pages); + +extern void osd_req_op_cls_init(struct ceph_osd_request *osd_req, + unsigned int which, u16 opcode, + const char *class, const char *method); +extern void osd_req_op_watch_init(struct ceph_osd_request *osd_req, + unsigned int which, u16 opcode, + u64 cookie, u64 version, int flag); + extern struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc, struct ceph_snap_context *snapc, - unsigned int num_op, + unsigned int num_ops, bool use_mempool, gfp_t gfp_flags); -extern void ceph_osdc_build_request(struct ceph_osd_request *req, - u64 off, u64 len, - unsigned int num_op, - struct ceph_osd_req_op *src_ops, +extern void ceph_osdc_build_request(struct ceph_osd_request *req, u64 off, struct ceph_snap_context *snapc, u64 snap_id, struct timespec *mtime); @@ -241,12 +307,11 @@ extern void ceph_osdc_build_request(struct ceph_osd_request *req, extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *, struct ceph_file_layout *layout, struct ceph_vino vino, - u64 offset, u64 *len, int op, int flags, + u64 offset, u64 *len, + int num_ops, int opcode, int flags, struct ceph_snap_context *snapc, - int do_sync, u32 truncate_seq, - u64 truncate_size, - struct timespec *mtime, - bool use_mempool, int page_align); + u32 truncate_seq, u64 truncate_size, + bool use_mempool); extern void ceph_osdc_set_request_linger(struct ceph_osd_client *osdc, struct ceph_osd_request *req); @@ -270,6 +335,8 @@ extern int ceph_osdc_wait_request(struct ceph_osd_client *osdc, struct ceph_osd_request *req); extern void ceph_osdc_sync(struct ceph_osd_client *osdc); +extern void ceph_osdc_flush_notifies(struct ceph_osd_client *osdc); + extern int ceph_osdc_readpages(struct ceph_osd_client *osdc, struct ceph_vino vino, struct ceph_file_layout *layout, diff --git a/include/linux/ceph/osdmap.h b/include/linux/ceph/osdmap.h index c819190d1642..d05cc4451af6 100644 --- a/include/linux/ceph/osdmap.h +++ b/include/linux/ceph/osdmap.h @@ -3,6 +3,7 @@ #include <linux/rbtree.h> #include <linux/ceph/types.h> +#include <linux/ceph/decode.h> #include <linux/ceph/ceph_fs.h> #include <linux/crush/crush.h> @@ -119,6 +120,29 @@ static inline struct ceph_entity_addr *ceph_osd_addr(struct ceph_osdmap *map, return &map->osd_addr[osd]; } +static inline int ceph_decode_pgid(void **p, void *end, struct ceph_pg *pgid) +{ + __u8 version; + + if (!ceph_has_room(p, end, 1 + 8 + 4 + 4)) { + pr_warning("incomplete pg encoding"); + + return -EINVAL; + } + version = ceph_decode_8(p); + if (version > 1) { + pr_warning("do not understand pg encoding %d > 1", + (int)version); + return -EINVAL; + } + + pgid->pool = ceph_decode_64(p); + pgid->seed = ceph_decode_32(p); + *p += 4; /* skip deprecated preferred value */ + + return 0; +} + extern struct ceph_osdmap *osdmap_decode(void **p, void *end); extern struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, struct ceph_osdmap *map, @@ -131,10 +155,8 @@ extern int ceph_calc_file_object_mapping(struct ceph_file_layout *layout, u64 *bno, u64 *oxoff, u64 *oxlen); /* calculate mapping of object to a placement group */ -extern int ceph_calc_object_layout(struct ceph_pg *pg, - const char *oid, - struct ceph_file_layout *fl, - struct ceph_osdmap *osdmap); +extern int ceph_calc_ceph_pg(struct ceph_pg *pg, const char *oid, + struct ceph_osdmap *osdmap, uint64_t pool); extern int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid, int *acting); diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 900af5964f55..39c1d9469677 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -19,6 +19,8 @@ #include <linux/idr.h> #include <linux/workqueue.h> #include <linux/xattr.h> +#include <linux/fs.h> +#include <linux/percpu-refcount.h> #ifdef CONFIG_CGROUPS @@ -27,13 +29,10 @@ struct cgroup_subsys; struct inode; struct cgroup; struct css_id; +struct eventfd_ctx; extern int cgroup_init_early(void); extern int cgroup_init(void); -extern void cgroup_lock(void); -extern int cgroup_lock_is_held(void); -extern bool cgroup_lock_live_group(struct cgroup *cgrp); -extern void cgroup_unlock(void); extern void cgroup_fork(struct task_struct *p); extern void cgroup_post_fork(struct task_struct *p); extern void cgroup_exit(struct task_struct *p, int run_callbacks); @@ -42,41 +41,50 @@ extern int cgroupstats_build(struct cgroupstats *stats, extern int cgroup_load_subsys(struct cgroup_subsys *ss); extern void cgroup_unload_subsys(struct cgroup_subsys *ss); -extern const struct file_operations proc_cgroup_operations; +extern int proc_cgroup_show(struct seq_file *, void *); -/* Define the enumeration of all builtin cgroup subsystems */ +/* + * Define the enumeration of all cgroup subsystems. + * + * We define ids for builtin subsystems and then modular ones. + */ #define SUBSYS(_x) _x ## _subsys_id, -#define IS_SUBSYS_ENABLED(option) IS_ENABLED(option) enum cgroup_subsys_id { +#define IS_SUBSYS_ENABLED(option) IS_BUILTIN(option) #include <linux/cgroup_subsys.h> +#undef IS_SUBSYS_ENABLED + CGROUP_BUILTIN_SUBSYS_COUNT, + + __CGROUP_SUBSYS_TEMP_PLACEHOLDER = CGROUP_BUILTIN_SUBSYS_COUNT - 1, + +#define IS_SUBSYS_ENABLED(option) IS_MODULE(option) +#include <linux/cgroup_subsys.h> +#undef IS_SUBSYS_ENABLED CGROUP_SUBSYS_COUNT, }; -#undef IS_SUBSYS_ENABLED #undef SUBSYS /* Per-subsystem/per-cgroup state maintained by the system. */ struct cgroup_subsys_state { - /* - * The cgroup that this subsystem is attached to. Useful - * for subsystems that want to know about the cgroup - * hierarchy structure - */ + /* the cgroup that this css is attached to */ struct cgroup *cgroup; - /* - * State maintained by the cgroup system to allow subsystems - * to be "busy". Should be accessed via css_get(), - * css_tryget() and css_put(). - */ + /* the cgroup subsystem that this css is attached to */ + struct cgroup_subsys *ss; - atomic_t refcnt; + /* reference count - access via css_[try]get() and css_put() */ + struct percpu_ref refcnt; + + /* the parent css */ + struct cgroup_subsys_state *parent; unsigned long flags; /* ID for this css, if possible */ struct css_id __rcu *id; - /* Used to put @cgroup->dentry on the last css_put() */ - struct work_struct dput_work; + /* percpu_ref killing and RCU release */ + struct rcu_head rcu_head; + struct work_struct destroy_work; }; /* bits in struct cgroup_subsys_state flags field */ @@ -85,56 +93,52 @@ enum { CSS_ONLINE = (1 << 1), /* between ->css_online() and ->css_offline() */ }; -/* Caller must verify that the css is not for root cgroup */ -static inline void __css_get(struct cgroup_subsys_state *css, int count) -{ - atomic_add(count, &css->refcnt); -} - -/* - * Call css_get() to hold a reference on the css; it can be used - * for a reference obtained via: - * - an existing ref-counted reference to the css - * - task->cgroups for a locked task +/** + * css_get - obtain a reference on the specified css + * @css: target css + * + * The caller must already have a reference. */ - static inline void css_get(struct cgroup_subsys_state *css) { /* We don't need to reference count the root state */ if (!(css->flags & CSS_ROOT)) - __css_get(css, 1); + percpu_ref_get(&css->refcnt); } -/* - * Call css_tryget() to take a reference on a css if your existing - * (known-valid) reference isn't already ref-counted. Returns false if - * the css has been destroyed. +/** + * css_tryget - try to obtain a reference on the specified css + * @css: target css + * + * Obtain a reference on @css if it's alive. The caller naturally needs to + * ensure that @css is accessible but doesn't have to be holding a + * reference on it - IOW, RCU protected access is good enough for this + * function. Returns %true if a reference count was successfully obtained; + * %false otherwise. */ - -extern bool __css_tryget(struct cgroup_subsys_state *css); static inline bool css_tryget(struct cgroup_subsys_state *css) { if (css->flags & CSS_ROOT) return true; - return __css_tryget(css); + return percpu_ref_tryget(&css->refcnt); } -/* - * css_put() should be called to release a reference taken by - * css_get() or css_tryget() +/** + * css_put - put a css reference + * @css: target css + * + * Put a reference obtained via css_get() and css_tryget(). */ - -extern void __css_put(struct cgroup_subsys_state *css); static inline void css_put(struct cgroup_subsys_state *css) { if (!(css->flags & CSS_ROOT)) - __css_put(css); + percpu_ref_put(&css->refcnt); } /* bits in struct cgroup flags field */ enum { /* Control Group is dead */ - CGRP_REMOVED, + CGRP_DEAD, /* * Control Group has previously had a child cgroup or a task, * but no longer (only if CGRP_NOTIFY_ON_RELEASE is set) @@ -148,18 +152,28 @@ enum { * specified at mount time and thus is implemented here. */ CGRP_CPUSET_CLONE_CHILDREN, + /* see the comment above CGRP_ROOT_SANE_BEHAVIOR for details */ + CGRP_SANE_BEHAVIOR, +}; + +struct cgroup_name { + struct rcu_head rcu_head; + char name[]; }; struct cgroup { unsigned long flags; /* "unsigned long" so bitops work */ /* - * count users of this cgroup. >0 means busy, but doesn't - * necessarily indicate the number of tasks in the cgroup + * idr allocated in-hierarchy ID. + * + * The ID of the root cgroup is always 0, and a new cgroup + * will be assigned with a smallest available ID. */ - atomic_t count; + int id; - int id; /* ida allocated in-hierarchy ID */ + /* the number of attached css's */ + int nr_css; /* * We link our 'sibling' struct into our parent's 'children'. @@ -172,20 +186,37 @@ struct cgroup { struct cgroup *parent; /* my parent */ struct dentry *dentry; /* cgroup fs entry, RCU protected */ + /* + * Monotonically increasing unique serial number which defines a + * uniform order among all cgroups. It's guaranteed that all + * ->children lists are in the ascending order of ->serial_nr. + * It's used to allow interrupting and resuming iterations. + */ + u64 serial_nr; + + /* + * This is a copy of dentry->d_name, and it's needed because + * we can't use dentry->d_name in cgroup_path(). + * + * You must acquire rcu_read_lock() to access cgrp->name, and + * the only place that can change it is rename(), which is + * protected by parent dir's i_mutex. + * + * Normally you should use cgroup_name() wrapper rather than + * access it directly. + */ + struct cgroup_name __rcu *name; + /* Private pointers for each registered subsystem */ - struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; + struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT]; struct cgroupfs_root *root; - struct cgroup *top_cgroup; /* - * List of cg_cgroup_links pointing at css_sets with - * tasks in this cgroup. Protected by css_set_lock + * List of cgrp_cset_links pointing at css_sets with tasks in this + * cgroup. Protected by css_set_lock. */ - struct list_head css_sets; - - struct list_head allcg_node; /* cgroupfs_root->allcg_list */ - struct list_head cft_q_node; /* used during cftype add/rm */ + struct list_head cset_links; /* * Linked list running through all cgroups that can @@ -201,9 +232,12 @@ struct cgroup { struct list_head pidlists; struct mutex pidlist_mutex; - /* For RCU-protected deletion */ + /* dummy css with NULL ->ss, points back to this cgroup */ + struct cgroup_subsys_state dummy_css; + + /* For css percpu_ref killing and RCU-protected deletion */ struct rcu_head rcu_head; - struct work_struct free_work; + struct work_struct destroy_work; /* List of events which userspace want to receive */ struct list_head event_list; @@ -213,6 +247,104 @@ struct cgroup { struct simple_xattrs xattrs; }; +#define MAX_CGROUP_ROOT_NAMELEN 64 + +/* cgroupfs_root->flags */ +enum { + /* + * Unfortunately, cgroup core and various controllers are riddled + * with idiosyncrasies and pointless options. The following flag, + * when set, will force sane behavior - some options are forced on, + * others are disallowed, and some controllers will change their + * hierarchical or other behaviors. + * + * The set of behaviors affected by this flag are still being + * determined and developed and the mount option for this flag is + * prefixed with __DEVEL__. The prefix will be dropped once we + * reach the point where all behaviors are compatible with the + * planned unified hierarchy, which will automatically turn on this + * flag. + * + * The followings are the behaviors currently affected this flag. + * + * - Mount options "noprefix" and "clone_children" are disallowed. + * Also, cgroupfs file cgroup.clone_children is not created. + * + * - When mounting an existing superblock, mount options should + * match. + * + * - Remount is disallowed. + * + * - rename(2) is disallowed. + * + * - "tasks" is removed. Everything should be at process + * granularity. Use "cgroup.procs" instead. + * + * - "release_agent" and "notify_on_release" are removed. + * Replacement notification mechanism will be implemented. + * + * - cpuset: tasks will be kept in empty cpusets when hotplug happens + * and take masks of ancestors with non-empty cpus/mems, instead of + * being moved to an ancestor. + * + * - cpuset: a task can be moved into an empty cpuset, and again it + * takes masks of ancestors. + * + * - memcg: use_hierarchy is on by default and the cgroup file for + * the flag is not created. + * + * - blkcg: blk-throttle becomes properly hierarchical. + */ + CGRP_ROOT_SANE_BEHAVIOR = (1 << 0), + + CGRP_ROOT_NOPREFIX = (1 << 1), /* mounted subsystems have no named prefix */ + CGRP_ROOT_XATTR = (1 << 2), /* supports extended attributes */ + + /* mount options live below bit 16 */ + CGRP_ROOT_OPTION_MASK = (1 << 16) - 1, + + CGRP_ROOT_SUBSYS_BOUND = (1 << 16), /* subsystems finished binding */ +}; + +/* + * A cgroupfs_root represents the root of a cgroup hierarchy, and may be + * associated with a superblock to form an active hierarchy. This is + * internal to cgroup core. Don't access directly from controllers. + */ +struct cgroupfs_root { + struct super_block *sb; + + /* The bitmask of subsystems attached to this hierarchy */ + unsigned long subsys_mask; + + /* Unique id for this hierarchy. */ + int hierarchy_id; + + /* A list running through the attached subsystems */ + struct list_head subsys_list; + + /* The root cgroup for this hierarchy */ + struct cgroup top_cgroup; + + /* Tracks how many cgroups are currently defined in hierarchy.*/ + int number_of_cgroups; + + /* A list running through the active hierarchies */ + struct list_head root_list; + + /* Hierarchy-specific flags */ + unsigned long flags; + + /* IDs for cgroups in this hierarchy */ + struct idr cgroup_idr; + + /* The path to use for release notifications. */ + char release_agent_path[PATH_MAX]; + + /* The name for this hierarchy - may be empty */ + char name[MAX_CGROUP_ROOT_NAMELEN]; +}; + /* * A css_set is a structure holding pointers to a set of * cgroup_subsys_state objects. This saves space in the task struct @@ -239,11 +371,10 @@ struct css_set { struct list_head tasks; /* - * List of cg_cgroup_link objects on link chains from - * cgroups referenced from this css_set. Protected by - * css_set_lock + * List of cgrp_cset_links pointing at cgroups referenced from this + * css_set. Protected by css_set_lock. */ - struct list_head cg_links; + struct list_head cgrp_links; /* * Set of subsystem states, one for each subsystem. This array @@ -276,8 +407,12 @@ struct cgroup_map_cb { */ /* cftype->flags */ -#define CFTYPE_ONLY_ON_ROOT (1U << 0) /* only create on root cg */ -#define CFTYPE_NOT_ON_ROOT (1U << 1) /* don't create on root cg */ +enum { + CFTYPE_ONLY_ON_ROOT = (1 << 0), /* only create on root cgrp */ + CFTYPE_NOT_ON_ROOT = (1 << 1), /* don't create on root cgrp */ + CFTYPE_INSANE = (1 << 2), /* don't create if sane_behavior */ + CFTYPE_NO_PREFIX = (1 << 3), /* (DON'T USE FOR NEW FILES) no subsys prefix */ +}; #define MAX_CFTYPE_NAME 64 @@ -304,38 +439,41 @@ struct cftype { /* CFTYPE_* flags */ unsigned int flags; - /* file xattrs */ - struct simple_xattrs xattrs; + /* + * The subsys this file belongs to. Initialized automatically + * during registration. NULL for cgroup core files. + */ + struct cgroup_subsys *ss; int (*open)(struct inode *inode, struct file *file); - ssize_t (*read)(struct cgroup *cgrp, struct cftype *cft, + ssize_t (*read)(struct cgroup_subsys_state *css, struct cftype *cft, struct file *file, char __user *buf, size_t nbytes, loff_t *ppos); /* * read_u64() is a shortcut for the common case of returning a * single integer. Use it in place of read() */ - u64 (*read_u64)(struct cgroup *cgrp, struct cftype *cft); + u64 (*read_u64)(struct cgroup_subsys_state *css, struct cftype *cft); /* * read_s64() is a signed version of read_u64() */ - s64 (*read_s64)(struct cgroup *cgrp, struct cftype *cft); + s64 (*read_s64)(struct cgroup_subsys_state *css, struct cftype *cft); /* * read_map() is used for defining a map of key/value * pairs. It should call cb->fill(cb, key, value) for each * entry. The key/value pairs (and their ordering) should not * change between reboots. */ - int (*read_map)(struct cgroup *cont, struct cftype *cft, + int (*read_map)(struct cgroup_subsys_state *css, struct cftype *cft, struct cgroup_map_cb *cb); /* * read_seq_string() is used for outputting a simple sequence * using seqfile. */ - int (*read_seq_string)(struct cgroup *cont, struct cftype *cft, - struct seq_file *m); + int (*read_seq_string)(struct cgroup_subsys_state *css, + struct cftype *cft, struct seq_file *m); - ssize_t (*write)(struct cgroup *cgrp, struct cftype *cft, + ssize_t (*write)(struct cgroup_subsys_state *css, struct cftype *cft, struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos); @@ -344,18 +482,20 @@ struct cftype { * a single integer (as parsed by simple_strtoull) from * userspace. Use in place of write(); return 0 or error. */ - int (*write_u64)(struct cgroup *cgrp, struct cftype *cft, u64 val); + int (*write_u64)(struct cgroup_subsys_state *css, struct cftype *cft, + u64 val); /* * write_s64() is a signed version of write_u64() */ - int (*write_s64)(struct cgroup *cgrp, struct cftype *cft, s64 val); + int (*write_s64)(struct cgroup_subsys_state *css, struct cftype *cft, + s64 val); /* * write_string() is passed a nul-terminated kernelspace * buffer of maximum length determined by max_write_len. * Returns 0 or -ve error code. */ - int (*write_string)(struct cgroup *cgrp, struct cftype *cft, + int (*write_string)(struct cgroup_subsys_state *css, struct cftype *cft, const char *buffer); /* * trigger() callback can be used to get some kick from the @@ -363,7 +503,7 @@ struct cftype { * at all. The private field can be used to determine the * kick type for multiplexing. */ - int (*trigger)(struct cgroup *cgrp, unsigned int event); + int (*trigger)(struct cgroup_subsys_state *css, unsigned int event); int (*release)(struct inode *inode, struct file *file); @@ -373,16 +513,18 @@ struct cftype { * you want to provide this functionality. Use eventfd_signal() * on eventfd to send notification to userspace. */ - int (*register_event)(struct cgroup *cgrp, struct cftype *cft, - struct eventfd_ctx *eventfd, const char *args); + int (*register_event)(struct cgroup_subsys_state *css, + struct cftype *cft, struct eventfd_ctx *eventfd, + const char *args); /* * unregister_event() callback will be called when userspace * closes the eventfd or on cgroup removing. * This callback must be implemented, if you want provide * notification functionality. */ - void (*unregister_event)(struct cgroup *cgrp, struct cftype *cft, - struct eventfd_ctx *eventfd); + void (*unregister_event)(struct cgroup_subsys_state *css, + struct cftype *cft, + struct eventfd_ctx *eventfd); }; /* @@ -395,27 +537,31 @@ struct cftype_set { struct cftype *cfts; }; -struct cgroup_scanner { - struct cgroup *cg; - int (*test_task)(struct task_struct *p, struct cgroup_scanner *scan); - void (*process_task)(struct task_struct *p, - struct cgroup_scanner *scan); - struct ptr_heap *heap; - void *data; -}; +/* + * See the comment above CGRP_ROOT_SANE_BEHAVIOR for details. This + * function can be called as long as @cgrp is accessible. + */ +static inline bool cgroup_sane_behavior(const struct cgroup *cgrp) +{ + return cgrp->root->flags & CGRP_ROOT_SANE_BEHAVIOR; +} + +/* Caller should hold rcu_read_lock() */ +static inline const char *cgroup_name(const struct cgroup *cgrp) +{ + return rcu_dereference(cgrp->name)->name; +} int cgroup_add_cftypes(struct cgroup_subsys *ss, struct cftype *cfts); -int cgroup_rm_cftypes(struct cgroup_subsys *ss, struct cftype *cfts); +int cgroup_rm_cftypes(struct cftype *cfts); -int cgroup_is_removed(const struct cgroup *cgrp); +bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor); int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen); +int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen); int cgroup_task_count(const struct cgroup *cgrp); -/* Return true if cgrp is a descendant of the task's cgroup */ -int cgroup_is_descendant(const struct cgroup *cgrp, struct task_struct *task); - /* * Control Group taskset, used to pass around set of tasks to cgroup_subsys * methods. @@ -423,20 +569,22 @@ int cgroup_is_descendant(const struct cgroup *cgrp, struct task_struct *task); struct cgroup_taskset; struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset); struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset); -struct cgroup *cgroup_taskset_cur_cgroup(struct cgroup_taskset *tset); +struct cgroup_subsys_state *cgroup_taskset_cur_css(struct cgroup_taskset *tset, + int subsys_id); int cgroup_taskset_size(struct cgroup_taskset *tset); /** * cgroup_taskset_for_each - iterate cgroup_taskset * @task: the loop cursor - * @skip_cgrp: skip if task's cgroup matches this, %NULL to iterate through all + * @skip_css: skip if task's css matches this, %NULL to iterate through all * @tset: taskset to iterate */ -#define cgroup_taskset_for_each(task, skip_cgrp, tset) \ +#define cgroup_taskset_for_each(task, skip_css, tset) \ for ((task) = cgroup_taskset_first((tset)); (task); \ (task) = cgroup_taskset_next((tset))) \ - if (!(skip_cgrp) || \ - cgroup_taskset_cur_cgroup((tset)) != (skip_cgrp)) + if (!(skip_css) || \ + cgroup_taskset_cur_css((tset), \ + (skip_css)->ss->subsys_id) != (skip_css)) /* * Control Group subsystem type. @@ -444,28 +592,26 @@ int cgroup_taskset_size(struct cgroup_taskset *tset); */ struct cgroup_subsys { - struct cgroup_subsys_state *(*css_alloc)(struct cgroup *cgrp); - int (*css_online)(struct cgroup *cgrp); - void (*css_offline)(struct cgroup *cgrp); - void (*css_free)(struct cgroup *cgrp); - - int (*can_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset); - void (*cancel_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset); - void (*attach)(struct cgroup *cgrp, struct cgroup_taskset *tset); + struct cgroup_subsys_state *(*css_alloc)(struct cgroup_subsys_state *parent_css); + int (*css_online)(struct cgroup_subsys_state *css); + void (*css_offline)(struct cgroup_subsys_state *css); + void (*css_free)(struct cgroup_subsys_state *css); + + int (*can_attach)(struct cgroup_subsys_state *css, + struct cgroup_taskset *tset); + void (*cancel_attach)(struct cgroup_subsys_state *css, + struct cgroup_taskset *tset); + void (*attach)(struct cgroup_subsys_state *css, + struct cgroup_taskset *tset); void (*fork)(struct task_struct *task); - void (*exit)(struct cgroup *cgrp, struct cgroup *old_cgrp, + void (*exit)(struct cgroup_subsys_state *css, + struct cgroup_subsys_state *old_css, struct task_struct *task); - void (*bind)(struct cgroup *root); + void (*bind)(struct cgroup_subsys_state *root_css); int subsys_id; - int active; int disabled; int early_init; - /* - * True if this subsys uses ID. ID is not available before cgroup_init() - * (not available in early_init time.) - */ - bool use_id; /* * If %false, this subsystem is properly hierarchical - @@ -491,9 +637,6 @@ struct cgroup_subsys { */ struct cgroupfs_root *root; struct list_head sibling; - /* used when use_id == true */ - struct idr idr; - spinlock_t id_lock; /* list of cftype_sets */ struct list_head cftsets; @@ -512,89 +655,153 @@ struct cgroup_subsys { #undef IS_SUBSYS_ENABLED #undef SUBSYS -static inline struct cgroup_subsys_state *cgroup_subsys_state( - struct cgroup *cgrp, int subsys_id) +/** + * css_parent - find the parent css + * @css: the target cgroup_subsys_state + * + * Return the parent css of @css. This function is guaranteed to return + * non-NULL parent as long as @css isn't the root. + */ +static inline +struct cgroup_subsys_state *css_parent(struct cgroup_subsys_state *css) { - return cgrp->subsys[subsys_id]; + return css->parent; } -/* - * function to get the cgroup_subsys_state which allows for extra - * rcu_dereference_check() conditions, such as locks used during the - * cgroup_subsys::attach() methods. +/** + * task_css_set_check - obtain a task's css_set with extra access conditions + * @task: the task to obtain css_set for + * @__c: extra condition expression to be passed to rcu_dereference_check() + * + * A task's css_set is RCU protected, initialized and exited while holding + * task_lock(), and can only be modified while holding both cgroup_mutex + * and task_lock() while the task is alive. This macro verifies that the + * caller is inside proper critical section and returns @task's css_set. + * + * The caller can also specify additional allowed conditions via @__c, such + * as locks used during the cgroup_subsys::attach() methods. + */ +#ifdef CONFIG_PROVE_RCU +extern struct mutex cgroup_mutex; +#define task_css_set_check(task, __c) \ + rcu_dereference_check((task)->cgroups, \ + lockdep_is_held(&(task)->alloc_lock) || \ + lockdep_is_held(&cgroup_mutex) || (__c)) +#else +#define task_css_set_check(task, __c) \ + rcu_dereference((task)->cgroups) +#endif + +/** + * task_css_check - obtain css for (task, subsys) w/ extra access conds + * @task: the target task + * @subsys_id: the target subsystem ID + * @__c: extra condition expression to be passed to rcu_dereference_check() + * + * Return the cgroup_subsys_state for the (@task, @subsys_id) pair. The + * synchronization rules are the same as task_css_set_check(). */ -#define task_subsys_state_check(task, subsys_id, __c) \ - rcu_dereference_check(task->cgroups->subsys[subsys_id], \ - lockdep_is_held(&task->alloc_lock) || \ - cgroup_lock_is_held() || (__c)) +#define task_css_check(task, subsys_id, __c) \ + task_css_set_check((task), (__c))->subsys[(subsys_id)] -static inline struct cgroup_subsys_state * -task_subsys_state(struct task_struct *task, int subsys_id) +/** + * task_css_set - obtain a task's css_set + * @task: the task to obtain css_set for + * + * See task_css_set_check(). + */ +static inline struct css_set *task_css_set(struct task_struct *task) +{ + return task_css_set_check(task, false); +} + +/** + * task_css - obtain css for (task, subsys) + * @task: the target task + * @subsys_id: the target subsystem ID + * + * See task_css_check(). + */ +static inline struct cgroup_subsys_state *task_css(struct task_struct *task, + int subsys_id) { - return task_subsys_state_check(task, subsys_id, false); + return task_css_check(task, subsys_id, false); } -static inline struct cgroup* task_cgroup(struct task_struct *task, - int subsys_id) +static inline struct cgroup *task_cgroup(struct task_struct *task, + int subsys_id) { - return task_subsys_state(task, subsys_id)->cgroup; + return task_css(task, subsys_id)->cgroup; } +struct cgroup_subsys_state *css_next_child(struct cgroup_subsys_state *pos, + struct cgroup_subsys_state *parent); + +struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss); + /** - * cgroup_for_each_child - iterate through children of a cgroup - * @pos: the cgroup * to use as the loop cursor - * @cgroup: cgroup whose children to walk + * css_for_each_child - iterate through children of a css + * @pos: the css * to use as the loop cursor + * @parent: css whose children to walk * - * Walk @cgroup's children. Must be called under rcu_read_lock(). A child - * cgroup which hasn't finished ->css_online() or already has finished + * Walk @parent's children. Must be called under rcu_read_lock(). A child + * css which hasn't finished ->css_online() or already has finished * ->css_offline() may show up during traversal and it's each subsystem's * responsibility to verify that each @pos is alive. * * If a subsystem synchronizes against the parent in its ->css_online() and - * before starting iterating, a cgroup which finished ->css_online() is + * before starting iterating, a css which finished ->css_online() is * guaranteed to be visible in the future iterations. + * + * It is allowed to temporarily drop RCU read lock during iteration. The + * caller is responsible for ensuring that @pos remains accessible until + * the start of the next iteration by, for example, bumping the css refcnt. */ -#define cgroup_for_each_child(pos, cgroup) \ - list_for_each_entry_rcu(pos, &(cgroup)->children, sibling) +#define css_for_each_child(pos, parent) \ + for ((pos) = css_next_child(NULL, (parent)); (pos); \ + (pos) = css_next_child((pos), (parent))) -struct cgroup *cgroup_next_descendant_pre(struct cgroup *pos, - struct cgroup *cgroup); -struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos); +struct cgroup_subsys_state * +css_next_descendant_pre(struct cgroup_subsys_state *pos, + struct cgroup_subsys_state *css); + +struct cgroup_subsys_state * +css_rightmost_descendant(struct cgroup_subsys_state *pos); /** - * cgroup_for_each_descendant_pre - pre-order walk of a cgroup's descendants - * @pos: the cgroup * to use as the loop cursor - * @cgroup: cgroup whose descendants to walk + * css_for_each_descendant_pre - pre-order walk of a css's descendants + * @pos: the css * to use as the loop cursor + * @root: css whose descendants to walk * - * Walk @cgroup's descendants. Must be called under rcu_read_lock(). A - * descendant cgroup which hasn't finished ->css_online() or already has + * Walk @root's descendants. @root is included in the iteration and the + * first node to be visited. Must be called under rcu_read_lock(). A + * descendant css which hasn't finished ->css_online() or already has * finished ->css_offline() may show up during traversal and it's each * subsystem's responsibility to verify that each @pos is alive. * * If a subsystem synchronizes against the parent in its ->css_online() and * before starting iterating, and synchronizes against @pos on each - * iteration, any descendant cgroup which finished ->css_offline() is + * iteration, any descendant css which finished ->css_online() is * guaranteed to be visible in the future iterations. * * In other words, the following guarantees that a descendant can't escape * state updates of its ancestors. * - * my_online(@cgrp) + * my_online(@css) * { - * Lock @cgrp->parent and @cgrp; - * Inherit state from @cgrp->parent; + * Lock @css's parent and @css; + * Inherit state from the parent; * Unlock both. * } * - * my_update_state(@cgrp) + * my_update_state(@css) * { - * Lock @cgrp; - * Update @cgrp's state; - * Unlock @cgrp; - * - * cgroup_for_each_descendant_pre(@pos, @cgrp) { + * css_for_each_descendant_pre(@pos, @css) { * Lock @pos; - * Verify @pos is alive and inherit state from @pos->parent; + * if (@pos == @css) + * Update @css's state; + * else + * Verify @pos is alive and inherit state from its parent; * Unlock @pos; * } * } @@ -605,8 +812,7 @@ struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos); * visible by walking order and, as long as inheriting operations to the * same @pos are atomic to each other, multiple updates racing each other * still result in the correct state. It's guaranateed that at least one - * inheritance happens for any cgroup after the latest update to its - * parent. + * inheritance happens for any css after the latest update to its parent. * * If checking parent's state requires locking the parent, each inheriting * iteration should lock and unlock both @pos->parent and @pos. @@ -614,94 +820,55 @@ struct cgroup *cgroup_rightmost_descendant(struct cgroup *pos); * Alternatively, a subsystem may choose to use a single global lock to * synchronize ->css_online() and ->css_offline() against tree-walking * operations. + * + * It is allowed to temporarily drop RCU read lock during iteration. The + * caller is responsible for ensuring that @pos remains accessible until + * the start of the next iteration by, for example, bumping the css refcnt. */ -#define cgroup_for_each_descendant_pre(pos, cgroup) \ - for (pos = cgroup_next_descendant_pre(NULL, (cgroup)); (pos); \ - pos = cgroup_next_descendant_pre((pos), (cgroup))) +#define css_for_each_descendant_pre(pos, css) \ + for ((pos) = css_next_descendant_pre(NULL, (css)); (pos); \ + (pos) = css_next_descendant_pre((pos), (css))) -struct cgroup *cgroup_next_descendant_post(struct cgroup *pos, - struct cgroup *cgroup); +struct cgroup_subsys_state * +css_next_descendant_post(struct cgroup_subsys_state *pos, + struct cgroup_subsys_state *css); /** - * cgroup_for_each_descendant_post - post-order walk of a cgroup's descendants - * @pos: the cgroup * to use as the loop cursor - * @cgroup: cgroup whose descendants to walk + * css_for_each_descendant_post - post-order walk of a css's descendants + * @pos: the css * to use as the loop cursor + * @css: css whose descendants to walk * - * Similar to cgroup_for_each_descendant_pre() but performs post-order - * traversal instead. Note that the walk visibility guarantee described in - * pre-order walk doesn't apply the same to post-order walks. + * Similar to css_for_each_descendant_pre() but performs post-order + * traversal instead. @root is included in the iteration and the last + * node to be visited. Note that the walk visibility guarantee described + * in pre-order walk doesn't apply the same to post-order walks. */ -#define cgroup_for_each_descendant_post(pos, cgroup) \ - for (pos = cgroup_next_descendant_post(NULL, (cgroup)); (pos); \ - pos = cgroup_next_descendant_post((pos), (cgroup))) - -/* A cgroup_iter should be treated as an opaque object */ -struct cgroup_iter { - struct list_head *cg_link; - struct list_head *task; +#define css_for_each_descendant_post(pos, css) \ + for ((pos) = css_next_descendant_post(NULL, (css)); (pos); \ + (pos) = css_next_descendant_post((pos), (css))) + +/* A css_task_iter should be treated as an opaque object */ +struct css_task_iter { + struct cgroup_subsys_state *origin_css; + struct list_head *cset_link; + struct list_head *task; }; -/* - * To iterate across the tasks in a cgroup: - * - * 1) call cgroup_iter_start to initialize an iterator - * - * 2) call cgroup_iter_next() to retrieve member tasks until it - * returns NULL or until you want to end the iteration - * - * 3) call cgroup_iter_end() to destroy the iterator. - * - * Or, call cgroup_scan_tasks() to iterate through every task in a - * cgroup - cgroup_scan_tasks() holds the css_set_lock when calling - * the test_task() callback, but not while calling the process_task() - * callback. - */ -void cgroup_iter_start(struct cgroup *cgrp, struct cgroup_iter *it); -struct task_struct *cgroup_iter_next(struct cgroup *cgrp, - struct cgroup_iter *it); -void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it); -int cgroup_scan_tasks(struct cgroup_scanner *scan); -int cgroup_attach_task(struct cgroup *, struct task_struct *); -int cgroup_attach_task_all(struct task_struct *from, struct task_struct *); - -/* - * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works - * if cgroup_subsys.use_id == true. It can be used for looking up and scanning. - * CSS ID is assigned at cgroup allocation (create) automatically - * and removed when subsys calls free_css_id() function. This is because - * the lifetime of cgroup_subsys_state is subsys's matter. - * - * Looking up and scanning function should be called under rcu_read_lock(). - * Taking cgroup_mutex is not necessary for following calls. - * But the css returned by this routine can be "not populated yet" or "being - * destroyed". The caller should check css and cgroup's status. - */ - -/* - * Typically Called at ->destroy(), or somewhere the subsys frees - * cgroup_subsys_state. - */ -void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css); - -/* Find a cgroup_subsys_state which has given ID */ +void css_task_iter_start(struct cgroup_subsys_state *css, + struct css_task_iter *it); +struct task_struct *css_task_iter_next(struct css_task_iter *it); +void css_task_iter_end(struct css_task_iter *it); -struct cgroup_subsys_state *css_lookup(struct cgroup_subsys *ss, int id); +int css_scan_tasks(struct cgroup_subsys_state *css, + bool (*test)(struct task_struct *, void *), + void (*process)(struct task_struct *, void *), + void *data, struct ptr_heap *heap); -/* - * Get a cgroup whose id is greater than or equal to id under tree of root. - * Returning a cgroup_subsys_state or NULL. - */ -struct cgroup_subsys_state *css_get_next(struct cgroup_subsys *ss, int id, - struct cgroup_subsys_state *root, int *foundid); - -/* Returns true if root is ancestor of cg */ -bool css_is_ancestor(struct cgroup_subsys_state *cg, - const struct cgroup_subsys_state *root); +int cgroup_attach_task_all(struct task_struct *from, struct task_struct *); +int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from); -/* Get id and depth of css */ -unsigned short css_id(struct cgroup_subsys_state *css); -unsigned short css_depth(struct cgroup_subsys_state *css); -struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id); +struct cgroup_subsys_state *css_from_dir(struct dentry *dentry, + struct cgroup_subsys *ss); #else /* !CONFIG_CGROUPS */ @@ -711,8 +878,6 @@ static inline void cgroup_fork(struct task_struct *p) {} static inline void cgroup_post_fork(struct task_struct *p) {} static inline void cgroup_exit(struct task_struct *p, int callbacks) {} -static inline void cgroup_lock(void) {} -static inline void cgroup_unlock(void) {} static inline int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry) { diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h index f204a7a9cf38..b613ffd402d1 100644 --- a/include/linux/cgroup_subsys.h +++ b/include/linux/cgroup_subsys.h @@ -1,80 +1,55 @@ -/* Add subsystem definitions of the form SUBSYS(<name>) in this - * file. Surround each one by a line of comment markers so that - * patches don't collide +/* + * List of cgroup subsystems. + * + * DO NOT ADD ANY SUBSYSTEM WITHOUT EXPLICIT ACKS FROM CGROUP MAINTAINERS. */ - -/* */ - -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_CPUSETS) SUBSYS(cpuset) #endif -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_DEBUG) SUBSYS(debug) #endif -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_SCHED) SUBSYS(cpu_cgroup) #endif -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_CPUACCT) SUBSYS(cpuacct) #endif -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_MEMCG) SUBSYS(mem_cgroup) #endif -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_DEVICE) SUBSYS(devices) #endif -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_FREEZER) SUBSYS(freezer) #endif -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_NET_CLS_CGROUP) SUBSYS(net_cls) #endif -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_BLK_CGROUP) SUBSYS(blkio) #endif -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_PERF) SUBSYS(perf) #endif -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_NETPRIO_CGROUP) SUBSYS(net_prio) #endif -/* */ - #if IS_SUBSYS_ENABLED(CONFIG_CGROUP_HUGETLB) SUBSYS(hugetlb) #endif - -/* */ +/* + * DO NOT ADD ANY SUBSYSTEM WITHOUT EXPLICIT ACKS FROM CGROUP MAINTAINERS. + */ diff --git a/include/linux/cleancache.h b/include/linux/cleancache.h index 42e55deee757..4ce9056b31a8 100644 --- a/include/linux/cleancache.h +++ b/include/linux/cleancache.h @@ -33,7 +33,7 @@ struct cleancache_ops { void (*invalidate_fs)(int); }; -extern struct cleancache_ops +extern struct cleancache_ops * cleancache_register_ops(struct cleancache_ops *ops); extern void __cleancache_init_fs(struct super_block *); extern void __cleancache_init_shared_fs(char *, struct super_block *); @@ -42,9 +42,9 @@ extern void __cleancache_put_page(struct page *); extern void __cleancache_invalidate_page(struct address_space *, struct page *); extern void __cleancache_invalidate_inode(struct address_space *); extern void __cleancache_invalidate_fs(struct super_block *); -extern int cleancache_enabled; #ifdef CONFIG_CLEANCACHE +#define cleancache_enabled (1) static inline bool cleancache_fs_enabled(struct page *page) { return page->mapping->host->i_sb->cleancache_poolid >= 0; diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h index 9c7f5807824b..8138c94409f3 100644 --- a/include/linux/clk-private.h +++ b/include/linux/clk-private.h @@ -33,8 +33,11 @@ struct clk { const char **parent_names; struct clk **parents; u8 num_parents; + u8 new_parent_index; unsigned long rate; unsigned long new_rate; + struct clk *new_parent; + struct clk *new_child; unsigned long flags; unsigned int enable_count; unsigned int prepare_count; @@ -152,7 +155,7 @@ struct clk { }, \ .reg = _reg, \ .shift = _shift, \ - .width = _width, \ + .mask = BIT(_width) - 1, \ .flags = _mux_flags, \ .lock = _lock, \ }; \ diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 7f197d7addb0..73bdb69f0c08 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -12,6 +12,7 @@ #define __LINUX_CLK_PROVIDER_H #include <linux/clk.h> +#include <linux/io.h> #ifdef CONFIG_COMMON_CLK @@ -27,6 +28,7 @@ #define CLK_IS_ROOT BIT(4) /* root clk, has no parent */ #define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */ #define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */ +#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ struct clk_hw; @@ -45,6 +47,14 @@ struct clk_hw; * undo any work done in the @prepare callback. Called with * prepare_lock held. * + * @is_prepared: Queries the hardware to determine if the clock is prepared. + * This function is allowed to sleep. Optional, if this op is not + * set then the prepare count will be used. + * + * @unprepare_unused: Unprepare the clock atomically. Only called from + * clk_disable_unused for prepare clocks with special needs. + * Called with prepare mutex held. This function may sleep. + * * @enable: Enable the clock atomically. This must not return until the * clock is generating a valid clock signal, usable by consumer * devices. Called with enable_lock held. This function must not @@ -71,6 +81,10 @@ struct clk_hw; * @round_rate: Given a target rate as input, returns the closest rate actually * supported by the clock. * + * @determine_rate: Given a target rate as input, returns the closest rate + * actually supported by the clock, and optionally the parent clock + * that should be used to provide the clock rate. + * * @get_parent: Queries the hardware to determine the parent of a clock. The * return value is a u8 which specifies the index corresponding to * the parent clock. This index can be applied to either the @@ -108,6 +122,8 @@ struct clk_hw; struct clk_ops { int (*prepare)(struct clk_hw *hw); void (*unprepare)(struct clk_hw *hw); + int (*is_prepared)(struct clk_hw *hw); + void (*unprepare_unused)(struct clk_hw *hw); int (*enable)(struct clk_hw *hw); void (*disable)(struct clk_hw *hw); int (*is_enabled)(struct clk_hw *hw); @@ -116,6 +132,9 @@ struct clk_ops { unsigned long parent_rate); long (*round_rate)(struct clk_hw *hw, unsigned long, unsigned long *); + long (*determine_rate)(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_clk); int (*set_parent)(struct clk_hw *hw, u8 index); u8 (*get_parent)(struct clk_hw *hw); int (*set_rate)(struct clk_hw *hw, unsigned long, @@ -200,6 +219,10 @@ void of_fixed_clk_setup(struct device_node *np); * CLK_GATE_SET_TO_DISABLE - by default this clock sets the bit at bit_idx to * enable the clock. Setting this flag does the opposite: setting the bit * disable the clock and clearing it enables the clock + * CLK_GATE_HIWORD_MASK - The gate settings are only in lower 16-bit + * of this register, and mask of gate bits are in higher 16-bit of this + * register. While setting the gate bits, higher 16-bit should also be + * updated to indicate changing gate bits. */ struct clk_gate { struct clk_hw hw; @@ -210,6 +233,7 @@ struct clk_gate { }; #define CLK_GATE_SET_TO_DISABLE BIT(0) +#define CLK_GATE_HIWORD_MASK BIT(1) extern const struct clk_ops clk_gate_ops; struct clk *clk_register_gate(struct device *dev, const char *name, @@ -239,9 +263,18 @@ struct clk_div_table { * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the * register plus one. If CLK_DIVIDER_ONE_BASED is set then the divider is * the raw value read from the register, with the value of zero considered - * invalid + * invalid, unless CLK_DIVIDER_ALLOW_ZERO is set. * CLK_DIVIDER_POWER_OF_TWO - clock divisor is 2 raised to the value read from * the hardware register + * CLK_DIVIDER_ALLOW_ZERO - Allow zero divisors. For dividers which have + * CLK_DIVIDER_ONE_BASED set, it is possible to end up with a zero divisor. + * Some hardware implementations gracefully handle this case and allow a + * zero divisor by not modifying their input clock + * (divide by one / bypass). + * CLK_DIVIDER_HIWORD_MASK - The divider settings are only in lower 16-bit + * of this register, and mask of divider bits are in higher 16-bit of this + * register. While setting the divider bits, higher 16-bit should also be + * updated to indicate changing divider bits. */ struct clk_divider { struct clk_hw hw; @@ -255,6 +288,8 @@ struct clk_divider { #define CLK_DIVIDER_ONE_BASED BIT(0) #define CLK_DIVIDER_POWER_OF_TWO BIT(1) +#define CLK_DIVIDER_ALLOW_ZERO BIT(2) +#define CLK_DIVIDER_HIWORD_MASK BIT(3) extern const struct clk_ops clk_divider_ops; struct clk *clk_register_divider(struct device *dev, const char *name, @@ -274,7 +309,7 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, * @reg: register controlling multiplexer * @shift: shift to multiplexer bit field * @width: width of mutliplexer bit field - * @num_clks: number of parent clocks + * @flags: hardware-specific flags * @lock: register lock * * Clock with multiple selectable parents. Implements .get_parent, .set_parent @@ -283,25 +318,41 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, * Flags: * CLK_MUX_INDEX_ONE - register index starts at 1, not 0 * CLK_MUX_INDEX_BIT - register index is a single bit (power of two) + * CLK_MUX_HIWORD_MASK - The mux settings are only in lower 16-bit of this + * register, and mask of mux bits are in higher 16-bit of this register. + * While setting the mux bits, higher 16-bit should also be updated to + * indicate changing mux bits. */ struct clk_mux { struct clk_hw hw; void __iomem *reg; + u32 *table; + u32 mask; u8 shift; - u8 width; u8 flags; spinlock_t *lock; }; #define CLK_MUX_INDEX_ONE BIT(0) #define CLK_MUX_INDEX_BIT BIT(1) +#define CLK_MUX_HIWORD_MASK BIT(2) +#define CLK_MUX_READ_ONLY BIT(3) /* mux setting cannot be changed */ extern const struct clk_ops clk_mux_ops; +extern const struct clk_ops clk_mux_ro_ops; + struct clk *clk_register_mux(struct device *dev, const char *name, const char **parent_names, u8 num_parents, unsigned long flags, void __iomem *reg, u8 shift, u8 width, u8 clk_mux_flags, spinlock_t *lock); +struct clk *clk_register_mux_table(struct device *dev, const char *name, + const char **parent_names, u8 num_parents, unsigned long flags, + void __iomem *reg, u8 shift, u32 mask, + u8 clk_mux_flags, u32 *table, spinlock_t *lock); + +void of_fixed_factor_clk_setup(struct device_node *node); + /** * struct clk_fixed_factor - fixed multiplier and divider clock * @@ -325,6 +376,37 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name, const char *parent_name, unsigned long flags, unsigned int mult, unsigned int div); +/*** + * struct clk_composite - aggregate clock of mux, divider and gate clocks + * + * @hw: handle between common and hardware-specific interfaces + * @mux_hw: handle between composite and hardware-specific mux clock + * @rate_hw: handle between composite and hardware-specific rate clock + * @gate_hw: handle between composite and hardware-specific gate clock + * @mux_ops: clock ops for mux + * @rate_ops: clock ops for rate + * @gate_ops: clock ops for gate + */ +struct clk_composite { + struct clk_hw hw; + struct clk_ops ops; + + struct clk_hw *mux_hw; + struct clk_hw *rate_hw; + struct clk_hw *gate_hw; + + const struct clk_ops *mux_ops; + const struct clk_ops *rate_ops; + const struct clk_ops *gate_ops; +}; + +struct clk *clk_register_composite(struct device *dev, const char *name, + const char **parent_names, int num_parents, + struct clk_hw *mux_hw, const struct clk_ops *mux_ops, + struct clk_hw *rate_hw, const struct clk_ops *rate_ops, + struct clk_hw *gate_hw, const struct clk_ops *gate_ops, + unsigned long flags); + /** * clk_register - allocate a new clock, register it and return an opaque cookie * @dev: device that is registering this clock @@ -347,12 +429,17 @@ const char *__clk_get_name(struct clk *clk); struct clk_hw *__clk_get_hw(struct clk *clk); u8 __clk_get_num_parents(struct clk *clk); struct clk *__clk_get_parent(struct clk *clk); +struct clk *clk_get_parent_by_index(struct clk *clk, u8 index); unsigned int __clk_get_enable_count(struct clk *clk); unsigned int __clk_get_prepare_count(struct clk *clk); unsigned long __clk_get_rate(struct clk *clk); unsigned long __clk_get_flags(struct clk *clk); +bool __clk_is_prepared(struct clk *clk); bool __clk_is_enabled(struct clk *clk); struct clk *__clk_lookup(const char *name); +long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p); /* * FIXME clock api without lock protection @@ -366,6 +453,17 @@ struct of_device_id; typedef void (*of_clk_init_cb_t)(struct device_node *); +struct clk_onecell_data { + struct clk **clks; + unsigned int clk_num; +}; + +#define CLK_OF_DECLARE(name, compat, fn) \ + static const struct of_device_id __clk_of_table_##name \ + __used __section(__clk_of_table) \ + = { .compatible = compat, .data = fn }; + +#ifdef CONFIG_OF int of_clk_add_provider(struct device_node *np, struct clk *(*clk_src_get)(struct of_phandle_args *args, void *data), @@ -373,19 +471,55 @@ int of_clk_add_provider(struct device_node *np, void of_clk_del_provider(struct device_node *np); struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, void *data); -struct clk_onecell_data { - struct clk **clks; - unsigned int clk_num; -}; struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data); const char *of_clk_get_parent_name(struct device_node *np, int index); void of_clk_init(const struct of_device_id *matches); -#define CLK_OF_DECLARE(name, compat, fn) \ - static const struct of_device_id __clk_of_table_##name \ - __used __section(__clk_of_table) \ - = { .compatible = compat, .data = fn }; +#else /* !CONFIG_OF */ + +static inline int of_clk_add_provider(struct device_node *np, + struct clk *(*clk_src_get)(struct of_phandle_args *args, + void *data), + void *data) +{ + return 0; +} +#define of_clk_del_provider(np) \ + { while (0); } +static inline struct clk *of_clk_src_simple_get( + struct of_phandle_args *clkspec, void *data) +{ + return ERR_PTR(-ENOENT); +} +static inline struct clk *of_clk_src_onecell_get( + struct of_phandle_args *clkspec, void *data) +{ + return ERR_PTR(-ENOENT); +} +static inline const char *of_clk_get_parent_name(struct device_node *np, + int index) +{ + return NULL; +} +#define of_clk_init(matches) \ + { while (0); } +#endif /* CONFIG_OF */ + +/* + * wrap access to peripherals in accessor routines + * for improved portability across platforms + */ + +static inline u32 clk_readl(u32 __iomem *reg) +{ + return readl(reg); +} + +static inline void clk_writel(u32 val, u32 __iomem *reg) +{ + writel(val, reg); +} #endif /* CONFIG_COMMON_CLK */ #endif /* CLK_PROVIDER_H */ diff --git a/include/linux/clk.h b/include/linux/clk.h index b3ac22d0fc1f..9a6d04524b1a 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -28,16 +28,16 @@ struct clk; * PRE_RATE_CHANGE - called immediately before the clk rate is changed, * to indicate that the rate change will proceed. Drivers must * immediately terminate any operations that will be affected by the - * rate change. Callbacks may either return NOTIFY_DONE or - * NOTIFY_STOP. + * rate change. Callbacks may either return NOTIFY_DONE, NOTIFY_OK, + * NOTIFY_STOP or NOTIFY_BAD. * * ABORT_RATE_CHANGE: called if the rate change failed for some reason * after PRE_RATE_CHANGE. In this case, all registered notifiers on * the clk will be called with ABORT_RATE_CHANGE. Callbacks must - * always return NOTIFY_DONE. + * always return NOTIFY_DONE or NOTIFY_OK. * * POST_RATE_CHANGE - called after the clk rate change has successfully - * completed. Callbacks must always return NOTIFY_DONE. + * completed. Callbacks must always return NOTIFY_DONE or NOTIFY_OK. * */ #define PRE_RATE_CHANGE BIT(0) diff --git a/include/linux/clk/mxs.h b/include/linux/clk/mxs.h new file mode 100644 index 000000000000..90c30dc3efc7 --- /dev/null +++ b/include/linux/clk/mxs.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2013 Freescale Semiconductor, Inc. + * + * 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_CLK_MXS_H +#define __LINUX_CLK_MXS_H + +int mx23_clocks_init(void); +int mx28_clocks_init(void); +int mxs_saif_clkmux_select(unsigned int clkmux); + +#endif diff --git a/include/linux/sunxi_timer.h b/include/linux/clk/sunxi.h index 18081787e5f3..e074fdd5a236 100644 --- a/include/linux/sunxi_timer.h +++ b/include/linux/clk/sunxi.h @@ -14,11 +14,9 @@ * GNU General Public License for more details. */ -#ifndef __SUNXI_TIMER_H -#define __SUNXI_TIMER_H +#ifndef __LINUX_CLK_SUNXI_H_ +#define __LINUX_CLK_SUNXI_H_ -#include <asm/mach/time.h> - -void sunxi_timer_init(void); +void __init sunxi_init_clocks(void); #endif diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h index 404d6f940872..23a0ceee831f 100644 --- a/include/linux/clk/tegra.h +++ b/include/linux/clk/tegra.h @@ -120,8 +120,13 @@ static inline void tegra_cpu_clock_resume(void) } #endif +#ifdef CONFIG_ARCH_TEGRA void tegra_periph_reset_deassert(struct clk *c); void tegra_periph_reset_assert(struct clk *c); -void tegra_clocks_init(void); +#else +static inline void tegra_periph_reset_deassert(struct clk *c) {} +static inline void tegra_periph_reset_assert(struct clk *c) {} +#endif +void tegra_clocks_apply_init_table(void); #endif /* __LINUX_CLK_TEGRA_H_ */ diff --git a/include/linux/clk/zynq.h b/include/linux/clk/zynq.h index 56be7cd9aa8b..e062d317ccce 100644 --- a/include/linux/clk/zynq.h +++ b/include/linux/clk/zynq.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2013 Xilinx Inc. * Copyright (C) 2012 National Instruments * * This program is free software; you can redistribute it and/or modify @@ -19,6 +20,11 @@ #ifndef __LINUX_CLK_ZYNQ_H_ #define __LINUX_CLK_ZYNQ_H_ -void __init xilinx_zynq_clocks_init(void __iomem *slcr); +#include <linux/spinlock.h> +void zynq_clock_init(void __iomem *slcr); + +struct clk *clk_register_zynq_pll(const char *name, const char *parent, + void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index, + spinlock_t *lock); #endif diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h index 66346521cb65..0857922e8ad0 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h @@ -8,6 +8,20 @@ #ifndef _LINUX_CLOCKCHIPS_H #define _LINUX_CLOCKCHIPS_H +/* Clock event notification values */ +enum clock_event_nofitiers { + CLOCK_EVT_NOTIFY_ADD, + CLOCK_EVT_NOTIFY_BROADCAST_ON, + CLOCK_EVT_NOTIFY_BROADCAST_OFF, + CLOCK_EVT_NOTIFY_BROADCAST_FORCE, + CLOCK_EVT_NOTIFY_BROADCAST_ENTER, + CLOCK_EVT_NOTIFY_BROADCAST_EXIT, + CLOCK_EVT_NOTIFY_SUSPEND, + CLOCK_EVT_NOTIFY_RESUME, + CLOCK_EVT_NOTIFY_CPU_DYING, + CLOCK_EVT_NOTIFY_CPU_DEAD, +}; + #ifdef CONFIG_GENERIC_CLOCKEVENTS_BUILD #include <linux/clocksource.h> @@ -16,6 +30,7 @@ #include <linux/notifier.h> struct clock_event_device; +struct module; /* Clock event mode commands */ enum clock_event_mode { @@ -26,20 +41,6 @@ enum clock_event_mode { CLOCK_EVT_MODE_RESUME, }; -/* Clock event notification values */ -enum clock_event_nofitiers { - CLOCK_EVT_NOTIFY_ADD, - CLOCK_EVT_NOTIFY_BROADCAST_ON, - CLOCK_EVT_NOTIFY_BROADCAST_OFF, - CLOCK_EVT_NOTIFY_BROADCAST_FORCE, - CLOCK_EVT_NOTIFY_BROADCAST_ENTER, - CLOCK_EVT_NOTIFY_BROADCAST_EXIT, - CLOCK_EVT_NOTIFY_SUSPEND, - CLOCK_EVT_NOTIFY_RESUME, - CLOCK_EVT_NOTIFY_CPU_DYING, - CLOCK_EVT_NOTIFY_CPU_DEAD, -}; - /* * Clock event features */ @@ -55,6 +56,11 @@ enum clock_event_nofitiers { #define CLOCK_EVT_FEAT_C3STOP 0x000008 #define CLOCK_EVT_FEAT_DUMMY 0x000010 +/* + * Core shall set the interrupt affinity dynamically in broadcast mode + */ +#define CLOCK_EVT_FEAT_DYNIRQ 0x000020 + /** * struct clock_event_device - clock event device descriptor * @event_handler: Assigned by the framework to be called by the low @@ -78,6 +84,7 @@ enum clock_event_nofitiers { * @irq: IRQ number (only for non CPU local devices) * @cpumask: cpumask to indicate for which CPUs this device works * @list: list head for the management code + * @owner: module reference */ struct clock_event_device { void (*event_handler)(struct clock_event_device *); @@ -107,6 +114,7 @@ struct clock_event_device { int irq; const struct cpumask *cpumask; struct list_head list; + struct module *owner; } ____cacheline_aligned; /* @@ -133,6 +141,7 @@ static inline unsigned long div_sc(unsigned long ticks, unsigned long nsec, extern u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt); extern void clockevents_register_device(struct clock_event_device *dev); +extern int clockevents_unbind_device(struct clock_event_device *ced, int cpu); extern void clockevents_config(struct clock_event_device *dev, u32 freq); extern void clockevents_config_and_register(struct clock_event_device *dev, @@ -145,7 +154,6 @@ extern void clockevents_exchange_device(struct clock_event_device *old, struct clock_event_device *new); extern void clockevents_set_mode(struct clock_event_device *dev, enum clock_event_mode mode); -extern int clockevents_register_notifier(struct notifier_block *nb); extern int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, bool force); @@ -170,10 +178,16 @@ extern void tick_broadcast(const struct cpumask *mask); extern int tick_receive_broadcast(void); #endif +#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT) +extern int tick_check_broadcast_expired(void); +#else +static inline int tick_check_broadcast_expired(void) { return 0; } +#endif + #ifdef CONFIG_GENERIC_CLOCKEVENTS extern void clockevents_notify(unsigned long reason, void *arg); #else -# define clockevents_notify(reason, arg) do { } while (0) +static inline void clockevents_notify(unsigned long reason, void *arg) {} #endif #else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */ @@ -181,7 +195,8 @@ extern void clockevents_notify(unsigned long reason, void *arg); static inline void clockevents_suspend(void) {} static inline void clockevents_resume(void) {} -#define clockevents_notify(reason, arg) do { } while (0) +static inline void clockevents_notify(unsigned long reason, void *arg) {} +static inline int tick_check_broadcast_expired(void) { return 0; } #endif diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 27cfda427dd9..67301a405712 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -21,6 +21,7 @@ /* clocksource cycle base type */ typedef u64 cycle_t; struct clocksource; +struct module; #ifdef CONFIG_ARCH_CLOCKSOURCE_DATA #include <asm/clocksource.h> @@ -162,6 +163,7 @@ extern u64 timecounter_cyc2time(struct timecounter *tc, * @suspend: suspend function for the clocksource, if necessary * @resume: resume function for the clocksource, if necessary * @cycle_last: most recent cycle counter value seen by ::read() + * @owner: module reference, must be set by clocksource in modules */ struct clocksource { /* @@ -195,6 +197,7 @@ struct clocksource { cycle_t cs_last; cycle_t wd_last; #endif + struct module *owner; } ____cacheline_aligned; /* @@ -206,6 +209,8 @@ struct clocksource { #define CLOCK_SOURCE_WATCHDOG 0x10 #define CLOCK_SOURCE_VALID_FOR_HRES 0x20 #define CLOCK_SOURCE_UNSTABLE 0x40 +#define CLOCK_SOURCE_SUSPEND_NONSTOP 0x80 +#define CLOCK_SOURCE_RESELECT 0x100 /* simplify initialization of mask field */ #define CLOCKSOURCE_MASK(bits) (cycle_t)((bits) < 64 ? ((1ULL<<(bits))-1) : -1) @@ -278,7 +283,7 @@ static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift) extern int clocksource_register(struct clocksource*); -extern void clocksource_unregister(struct clocksource*); +extern int clocksource_unregister(struct clocksource*); extern void clocksource_touch_watchdog(void); extern struct clocksource* clocksource_get_next(void); extern void clocksource_change_rating(struct clocksource *cs, int rating); @@ -287,6 +292,8 @@ extern void clocksource_resume(void); extern struct clocksource * __init __weak clocksource_default_clock(void); extern void clocksource_mark_unstable(struct clocksource *cs); +extern u64 +clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask); extern void clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec); @@ -320,7 +327,7 @@ static inline void __clocksource_updatefreq_khz(struct clocksource *cs, u32 khz) } -extern void timekeeping_notify(struct clocksource *clock); +extern int timekeeping_notify(struct clocksource *clock); extern cycle_t clocksource_mmio_readl_up(struct clocksource *); extern cycle_t clocksource_mmio_readl_down(struct clocksource *); @@ -332,15 +339,23 @@ extern int clocksource_mmio_init(void __iomem *, const char *, extern int clocksource_i8253_init(void); +struct device_node; +typedef void(*clocksource_of_init_fn)(struct device_node *); #ifdef CONFIG_CLKSRC_OF extern void clocksource_of_init(void); #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ static const struct of_device_id __clksrc_of_table_##name \ __used __section(__clksrc_of_table) \ - = { .compatible = compat, .data = fn }; + = { .compatible = compat, \ + .data = (fn == (clocksource_of_init_fn)NULL) ? fn : fn } #else -#define CLOCKSOURCE_OF_DECLARE(name, compat, fn) +static inline void clocksource_of_init(void) {} +#define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \ + static const struct of_device_id __clksrc_of_table_##name \ + __attribute__((unused)) \ + = { .compatible = compat, \ + .data = (fn == (clocksource_of_init_fn)NULL) ? fn : fn } #endif #endif /* _LINUX_CLOCKSOURCE_H */ diff --git a/include/linux/cmdline-parser.h b/include/linux/cmdline-parser.h new file mode 100644 index 000000000000..98e892ef6d5a --- /dev/null +++ b/include/linux/cmdline-parser.h @@ -0,0 +1,43 @@ +/* + * Parsing command line, get the partitions information. + * + * Written by Cai Zhiyong <caizhiyong@huawei.com> + * + */ +#ifndef CMDLINEPARSEH +#define CMDLINEPARSEH + +#include <linux/blkdev.h> + +/* partition flags */ +#define PF_RDONLY 0x01 /* Device is read only */ +#define PF_POWERUP_LOCK 0x02 /* Always locked after reset */ + +struct cmdline_subpart { + char name[BDEVNAME_SIZE]; /* partition name, such as 'rootfs' */ + sector_t from; + sector_t size; + int flags; + struct cmdline_subpart *next_subpart; +}; + +struct cmdline_parts { + char name[BDEVNAME_SIZE]; /* block device, such as 'mmcblk0' */ + unsigned int nr_subparts; + struct cmdline_subpart *subpart; + struct cmdline_parts *next_parts; +}; + +void cmdline_parts_free(struct cmdline_parts **parts); + +int cmdline_parts_parse(struct cmdline_parts **parts, const char *cmdline); + +struct cmdline_parts *cmdline_parts_find(struct cmdline_parts *parts, + const char *bdev); + +void cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size, + int slot, + int (*add_part)(int, struct cmdline_subpart *, void *), + void *param); + +#endif /* CMDLINEPARSEH */ diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h index 2c1bc1ea04ee..1d5b02a96c46 100644 --- a/include/linux/cn_proc.h +++ b/include/linux/cn_proc.h @@ -26,6 +26,7 @@ void proc_id_connector(struct task_struct *task, int which_id); void proc_sid_connector(struct task_struct *task); void proc_ptrace_connector(struct task_struct *task, int which_id); void proc_comm_connector(struct task_struct *task); +void proc_coredump_connector(struct task_struct *task); void proc_exit_connector(struct task_struct *task); #else static inline void proc_fork_connector(struct task_struct *task) @@ -48,6 +49,9 @@ static inline void proc_ptrace_connector(struct task_struct *task, int ptrace_id) {} +static inline void proc_coredump_connector(struct task_struct *task) +{} + static inline void proc_exit_connector(struct task_struct *task) {} #endif /* CONFIG_PROC_EVENTS */ diff --git a/include/linux/coda.h b/include/linux/coda.h index cff544f81105..d30209b9cef8 100644 --- a/include/linux/coda.h +++ b/include/linux/coda.h @@ -60,7 +60,6 @@ Mellon the rights to redistribute these changes without encumbrance. #if defined(__linux__) typedef unsigned long long u_quad_t; -#else #endif #include <uapi/linux/coda.h> #endif diff --git a/include/linux/compat.h b/include/linux/compat.h index 76a87fb57ac2..345da00a86e0 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -27,12 +27,6 @@ #define __SC_DELOUSE(t,v) ((t)(unsigned long)(v)) #endif -#define __SC_CCAST1(t1, a1) __SC_DELOUSE(t1,a1) -#define __SC_CCAST2(t2, a2, ...) __SC_DELOUSE(t2,a2), __SC_CCAST1(__VA_ARGS__) -#define __SC_CCAST3(t3, a3, ...) __SC_DELOUSE(t3,a3), __SC_CCAST2(__VA_ARGS__) -#define __SC_CCAST4(t4, a4, ...) __SC_DELOUSE(t4,a4), __SC_CCAST3(__VA_ARGS__) -#define __SC_CCAST5(t5, a5, ...) __SC_DELOUSE(t5,a5), __SC_CCAST4(__VA_ARGS__) -#define __SC_CCAST6(t6, a6, ...) __SC_DELOUSE(t6,a6), __SC_CCAST5(__VA_ARGS__) #define COMPAT_SYSCALL_DEFINE1(name, ...) \ COMPAT_SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) #define COMPAT_SYSCALL_DEFINE2(name, ...) \ @@ -46,24 +40,16 @@ #define COMPAT_SYSCALL_DEFINE6(name, ...) \ COMPAT_SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) -#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS - #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ - asmlinkage long compat_sys##name(__SC_DECL##x(__VA_ARGS__)); \ - static inline long C_SYSC##name(__SC_DECL##x(__VA_ARGS__)); \ - asmlinkage long compat_SyS##name(__SC_LONG##x(__VA_ARGS__)) \ + asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ + static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ + asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__));\ + asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))\ { \ - return (long) C_SYSC##name(__SC_CCAST##x(__VA_ARGS__)); \ + return C_SYSC##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \ } \ SYSCALL_ALIAS(compat_sys##name, compat_SyS##name); \ - static inline long C_SYSC##name(__SC_DECL##x(__VA_ARGS__)) - -#else /* CONFIG_HAVE_SYSCALL_WRAPPERS */ - -#define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ - asmlinkage long compat_sys##name(__SC_DECL##x(__VA_ARGS__)) - -#endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ + static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) #ifndef compat_user_stack_pointer #define compat_user_stack_pointer() current_user_stack_pointer() @@ -141,11 +127,11 @@ typedef struct { } compat_sigset_t; struct compat_sigaction { -#ifndef __ARCH_HAS_ODD_SIGACTION +#ifndef __ARCH_HAS_IRIX_SIGACTION compat_uptr_t sa_handler; compat_ulong_t sa_flags; #else - compat_ulong_t sa_flags; + compat_uint_t sa_flags; compat_uptr_t sa_handler; #endif #ifdef __ARCH_HAS_SA_RESTORER @@ -326,21 +312,13 @@ asmlinkage long compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, compat_size_t __user *len_ptr); -#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC -long compat_sys_semctl(int first, int second, int third, void __user *uptr); -long compat_sys_msgsnd(int first, int second, int third, void __user *uptr); -long compat_sys_msgrcv(int first, int second, int msgtyp, int third, - int version, void __user *uptr); -long compat_sys_shmat(int first, int second, compat_uptr_t third, int version, - void __user *uptr); -#else -long compat_sys_semctl(int semid, int semnum, int cmd, int arg); -long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp, +asmlinkage long compat_sys_ipc(u32, int, int, u32, compat_uptr_t, u32); +asmlinkage long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg); +asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg); +asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz, int msgflg); -long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp, +asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz, long msgtyp, int msgflg); -long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg); -#endif long compat_sys_msgctl(int first, int second, void __user *uptr); long compat_sys_shmctl(int first, int second, void __user *uptr); long compat_sys_semtimedop(int semid, struct sembuf __user *tsems, @@ -444,13 +422,13 @@ extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request, asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, compat_long_t addr, compat_long_t data); +asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, size_t); /* * epoll (fs/eventpoll.c) compat bits follow ... */ -struct epoll_event; -#define compat_epoll_event epoll_event +struct epoll_event; /* fortunately, this one is fixed-layout */ asmlinkage long compat_sys_epoll_pwait(int epfd, - struct compat_epoll_event __user *events, + struct epoll_event __user *events, int maxevents, int timeout, const compat_sigset_t __user *sigmask, compat_size_t sigsetsize); @@ -685,15 +663,26 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid, asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, compat_size_t count); +asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd, + compat_loff_t __user *offset, compat_size_t count); asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr, compat_stack_t __user *uoss_ptr); int compat_restore_altstack(const compat_stack_t __user *uss); int __compat_save_altstack(compat_stack_t __user *, unsigned long); +#define compat_save_altstack_ex(uss, sp) do { \ + compat_stack_t __user *__uss = uss; \ + struct task_struct *t = current; \ + put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp); \ + put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \ + put_user_ex(t->sas_ss_size, &__uss->ss_size); \ +} while (0); asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval); +asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32, + int, const char __user *); #else #define is_compat_task() (0) diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h index 68b162d92254..842de225055f 100644 --- a/include/linux/compiler-gcc4.h +++ b/include/linux/compiler-gcc4.h @@ -13,7 +13,7 @@ #define __must_check __attribute__((warn_unused_result)) #define __compiler_offsetof(a,b) __builtin_offsetof(a,b) -#if GCC_VERSION >= 40100 +#if GCC_VERSION >= 40100 && GCC_VERSION < 40600 # define __compiletime_object_size(obj) __builtin_object_size(obj, 0) #endif diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 10b8f23fab0f..92669cd182a6 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -351,4 +351,10 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); */ #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) +/* Ignore/forbid kprobes attach on very low level functions marked by this attribute: */ +#ifdef CONFIG_KPROBES +# define __kprobes __attribute__((__section__(".kprobes.text"))) +#else +# define __kprobes +#endif #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/completion.h b/include/linux/completion.h index 33f0280fd533..3cd574d5b19e 100644 --- a/include/linux/completion.h +++ b/include/linux/completion.h @@ -5,7 +5,7 @@ * (C) Copyright 2001 Linus Torvalds * * Atomic wait-for-completion handler data structures. - * See kernel/sched.c for details. + * See kernel/sched/core.c for details. */ #include <linux/wait.h> diff --git a/include/linux/console.h b/include/linux/console.h index 29680a8cda99..fdfcb703d7f5 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -75,10 +75,7 @@ extern const struct consw newport_con; /* SGI Newport console */ extern const struct consw prom_con; /* SPARC PROM console */ int con_is_bound(const struct consw *csw); -int register_con_driver(const struct consw *csw, int first, int last); -int unregister_con_driver(const struct consw *csw); int do_unregister_con_driver(const struct consw *csw); -int take_over_console(const struct consw *sw, int first, int last, int deflt); int do_take_over_console(const struct consw *sw, int first, int last, int deflt); void give_up_console(const struct consw *sw); #ifdef CONFIG_HW_CONSOLE @@ -118,6 +115,7 @@ static inline int con_debug_leave(void) #define CON_BOOT (8) #define CON_ANYTIME (16) /* Safe to call when cpu is offline */ #define CON_BRL (32) /* Used for a braille device */ +#define CON_ALLDATA (64) /* per-console ignore_loglevel */ struct console { char name[16]; @@ -141,6 +139,7 @@ struct console { for (con = console_drivers; con != NULL; con = con->next) extern int console_set_on_cmdline; +extern struct console *early_console; extern int add_preferred_console(char *name, int idx, char *options); extern int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options); diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h index b28d161c1091..158158704c30 100644 --- a/include/linux/context_tracking.h +++ b/include/linux/context_tracking.h @@ -1,46 +1,111 @@ #ifndef _LINUX_CONTEXT_TRACKING_H #define _LINUX_CONTEXT_TRACKING_H -#ifdef CONFIG_CONTEXT_TRACKING #include <linux/sched.h> -#include <linux/percpu.h> +#include <linux/vtime.h> +#include <linux/context_tracking_state.h> +#include <asm/ptrace.h> -struct context_tracking { - /* - * When active is false, probes are unset in order - * to minimize overhead: TIF flags are cleared - * and calls to user_enter/exit are ignored. This - * may be further optimized using static keys. - */ - bool active; - enum { - IN_KERNEL = 0, - IN_USER, - } state; -}; -DECLARE_PER_CPU(struct context_tracking, context_tracking); +#ifdef CONFIG_CONTEXT_TRACKING +extern void context_tracking_cpu_set(int cpu); + +extern void context_tracking_user_enter(void); +extern void context_tracking_user_exit(void); +extern void __context_tracking_task_switch(struct task_struct *prev, + struct task_struct *next); + +static inline void user_enter(void) +{ + if (static_key_false(&context_tracking_enabled)) + context_tracking_user_enter(); + +} +static inline void user_exit(void) +{ + if (static_key_false(&context_tracking_enabled)) + context_tracking_user_exit(); +} -static inline bool context_tracking_in_user(void) +static inline enum ctx_state exception_enter(void) { - return __this_cpu_read(context_tracking.state) == IN_USER; + enum ctx_state prev_ctx; + + if (!static_key_false(&context_tracking_enabled)) + return 0; + + prev_ctx = this_cpu_read(context_tracking.state); + context_tracking_user_exit(); + + return prev_ctx; } -static inline bool context_tracking_active(void) +static inline void exception_exit(enum ctx_state prev_ctx) { - return __this_cpu_read(context_tracking.active); + if (static_key_false(&context_tracking_enabled)) { + if (prev_ctx == IN_USER) + context_tracking_user_enter(); + } } -extern void user_enter(void); -extern void user_exit(void); -extern void context_tracking_task_switch(struct task_struct *prev, - struct task_struct *next); +static inline void context_tracking_task_switch(struct task_struct *prev, + struct task_struct *next) +{ + if (static_key_false(&context_tracking_enabled)) + __context_tracking_task_switch(prev, next); +} #else -static inline bool context_tracking_in_user(void) { return false; } static inline void user_enter(void) { } static inline void user_exit(void) { } +static inline enum ctx_state exception_enter(void) { return 0; } +static inline void exception_exit(enum ctx_state prev_ctx) { } static inline void context_tracking_task_switch(struct task_struct *prev, struct task_struct *next) { } #endif /* !CONFIG_CONTEXT_TRACKING */ + +#ifdef CONFIG_CONTEXT_TRACKING_FORCE +extern void context_tracking_init(void); +#else +static inline void context_tracking_init(void) { } +#endif /* CONFIG_CONTEXT_TRACKING_FORCE */ + + +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN +static inline void guest_enter(void) +{ + if (vtime_accounting_enabled()) + vtime_guest_enter(current); + else + current->flags |= PF_VCPU; +} + +static inline void guest_exit(void) +{ + if (vtime_accounting_enabled()) + vtime_guest_exit(current); + else + current->flags &= ~PF_VCPU; +} + +#else +static inline void guest_enter(void) +{ + /* + * This is running in ioctl context so its safe + * to assume that it's the stime pending cputime + * to flush. + */ + vtime_account_system(current); + current->flags |= PF_VCPU; +} + +static inline void guest_exit(void) +{ + /* Flush the guest cputime we spent on the guest */ + vtime_account_system(current); + current->flags &= ~PF_VCPU; +} +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */ + #endif diff --git a/include/linux/context_tracking_state.h b/include/linux/context_tracking_state.h new file mode 100644 index 000000000000..0f1979d0674f --- /dev/null +++ b/include/linux/context_tracking_state.h @@ -0,0 +1,39 @@ +#ifndef _LINUX_CONTEXT_TRACKING_STATE_H +#define _LINUX_CONTEXT_TRACKING_STATE_H + +#include <linux/percpu.h> +#include <linux/static_key.h> + +struct context_tracking { + /* + * When active is false, probes are unset in order + * to minimize overhead: TIF flags are cleared + * and calls to user_enter/exit are ignored. This + * may be further optimized using static keys. + */ + bool active; + enum ctx_state { + IN_KERNEL = 0, + IN_USER, + } state; +}; + +#ifdef CONFIG_CONTEXT_TRACKING +extern struct static_key context_tracking_enabled; +DECLARE_PER_CPU(struct context_tracking, context_tracking); + +static inline bool context_tracking_in_user(void) +{ + return __this_cpu_read(context_tracking.state) == IN_USER; +} + +static inline bool context_tracking_active(void) +{ + return __this_cpu_read(context_tracking.active); +} +#else +static inline bool context_tracking_in_user(void) { return false; } +static inline bool context_tracking_active(void) { return false; } +#endif /* CONFIG_CONTEXT_TRACKING */ + +#endif diff --git a/include/linux/cpu.h b/include/linux/cpu.h index ce7a074f2519..801ff9e73679 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -6,9 +6,8 @@ * definitions of processors. * * Basic handling of the devices is done in drivers/base/cpu.c - * and system devices are handled in drivers/base/sys.c. * - * CPUs are exported via sysfs in the class/cpu/devices/ + * CPUs are exported via sysfs in the devices/system/cpu * directory. */ #ifndef _LINUX_CPU_H_ @@ -29,6 +28,7 @@ struct cpu { extern int register_cpu(struct cpu *cpu, int num); extern struct device *get_cpu_device(unsigned cpu); extern bool cpu_is_hotpluggable(unsigned cpu); +extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id); extern int cpu_add_dev_attr(struct device_attribute *attr); extern void cpu_remove_dev_attr(struct device_attribute *attr); @@ -115,7 +115,7 @@ enum { /* Need to know about CPUs going up/down? */ #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) #define cpu_notifier(fn, pri) { \ - static struct notifier_block fn##_nb __cpuinitdata = \ + static struct notifier_block fn##_nb = \ { .notifier_call = fn, .priority = pri }; \ register_cpu_notifier(&fn##_nb); \ } @@ -173,8 +173,12 @@ extern struct bus_type cpu_subsys; #ifdef CONFIG_HOTPLUG_CPU /* Stop CPUs going up and down. */ +extern void cpu_hotplug_begin(void); +extern void cpu_hotplug_done(void); extern void get_online_cpus(void); extern void put_online_cpus(void); +extern void cpu_hotplug_disable(void); +extern void cpu_hotplug_enable(void); #define hotcpu_notifier(fn, pri) cpu_notifier(fn, pri) #define register_hotcpu_notifier(nb) register_cpu_notifier(nb) #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb) @@ -196,8 +200,12 @@ static inline void cpu_hotplug_driver_unlock(void) #else /* CONFIG_HOTPLUG_CPU */ +static inline void cpu_hotplug_begin(void) {} +static inline void cpu_hotplug_done(void) {} #define get_online_cpus() do { } while (0) #define put_online_cpus() do { } while (0) +#define cpu_hotplug_disable() do { } while (0) +#define cpu_hotplug_enable() do { } while (0) #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) /* These aren't inline functions due to a GCC bug. */ #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) @@ -212,4 +220,20 @@ static inline int disable_nonboot_cpus(void) { return 0; } static inline void enable_nonboot_cpus(void) {} #endif /* !CONFIG_PM_SLEEP_SMP */ +enum cpuhp_state { + CPUHP_OFFLINE, + CPUHP_ONLINE, +}; + +void cpu_startup_entry(enum cpuhp_state state); +void cpu_idle(void); + +void cpu_idle_poll_ctrl(bool enable); + +void arch_cpu_idle(void); +void arch_cpu_idle_prepare(void); +void arch_cpu_idle_enter(void); +void arch_cpu_idle_exit(void); +void arch_cpu_idle_dead(void); + #endif /* _LINUX_CPU_H_ */ diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index 40b4ef54cc7d..a5d52eea8232 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -25,34 +25,39 @@ #define __CPU_COOLING_H__ #include <linux/thermal.h> +#include <linux/cpumask.h> -#define CPUFREQ_COOLING_START 0 -#define CPUFREQ_COOLING_STOP 1 - -#if defined(CONFIG_CPU_THERMAL) || defined(CONFIG_CPU_THERMAL_MODULE) +#ifdef CONFIG_CPU_THERMAL /** * cpufreq_cooling_register - function to create cpufreq cooling device. * @clip_cpus: cpumask of cpus where the frequency constraints will happen */ -struct thermal_cooling_device *cpufreq_cooling_register( - const struct cpumask *clip_cpus); +struct thermal_cooling_device * +cpufreq_cooling_register(const struct cpumask *clip_cpus); /** * cpufreq_cooling_unregister - function to remove cpufreq cooling device. * @cdev: thermal cooling device pointer. */ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev); + +unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq); #else /* !CONFIG_CPU_THERMAL */ -static inline struct thermal_cooling_device *cpufreq_cooling_register( - const struct cpumask *clip_cpus) +static inline struct thermal_cooling_device * +cpufreq_cooling_register(const struct cpumask *clip_cpus) { return NULL; } -static inline void cpufreq_cooling_unregister( - struct thermal_cooling_device *cdev) +static inline +void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) { return; } +static inline +unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq) +{ + return THERMAL_CSTATE_INVALID; +} #endif /* CONFIG_CPU_THERMAL */ #endif /* __CPU_COOLING_H__ */ diff --git a/include/linux/cpu_rmap.h b/include/linux/cpu_rmap.h index 1739510d8994..bdd18caa6c94 100644 --- a/include/linux/cpu_rmap.h +++ b/include/linux/cpu_rmap.h @@ -52,8 +52,6 @@ static inline void *cpu_rmap_lookup_obj(struct cpu_rmap *rmap, unsigned int cpu) return rmap->obj[rmap->near[cpu].index]; } -#ifdef CONFIG_GENERIC_HARDIRQS - /** * alloc_irq_cpu_rmap - allocate CPU affinity reverse-map for IRQs * @size: Number of objects to be mapped @@ -68,5 +66,4 @@ extern void free_irq_cpu_rmap(struct cpu_rmap *rmap); extern int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq); -#endif #endif /* __LINUX_CPU_RMAP_H */ diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index a22944ca0526..fcabc42d66ab 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -1,8 +1,8 @@ /* - * linux/include/linux/cpufreq.h + * linux/include/linux/cpufreq.h * - * Copyright (C) 2001 Russell King - * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de> + * Copyright (C) 2001 Russell King + * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.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 @@ -11,68 +11,36 @@ #ifndef _LINUX_CPUFREQ_H #define _LINUX_CPUFREQ_H -#include <asm/cputime.h> -#include <linux/mutex.h> -#include <linux/notifier.h> -#include <linux/threads.h> +#include <linux/cpumask.h> +#include <linux/completion.h> #include <linux/kobject.h> +#include <linux/notifier.h> #include <linux/sysfs.h> -#include <linux/completion.h> -#include <linux/workqueue.h> -#include <linux/cpumask.h> -#include <asm/div64.h> - -#define CPUFREQ_NAME_LEN 16 -/* Print length for names. Extra 1 space for accomodating '\n' in prints */ -#define CPUFREQ_NAME_PLEN (CPUFREQ_NAME_LEN + 1) - /********************************************************************* - * CPUFREQ NOTIFIER INTERFACE * + * CPUFREQ INTERFACE * *********************************************************************/ - -#define CPUFREQ_TRANSITION_NOTIFIER (0) -#define CPUFREQ_POLICY_NOTIFIER (1) - -#ifdef CONFIG_CPU_FREQ -int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); -int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); -extern void disable_cpufreq(void); -#else /* CONFIG_CPU_FREQ */ -static inline int cpufreq_register_notifier(struct notifier_block *nb, - unsigned int list) -{ - return 0; -} -static inline int cpufreq_unregister_notifier(struct notifier_block *nb, - unsigned int list) -{ - return 0; -} -static inline void disable_cpufreq(void) { } -#endif /* CONFIG_CPU_FREQ */ - -/* if (cpufreq_driver->target) exists, the ->governor decides what frequency - * within the limits is used. If (cpufreq_driver->setpolicy> exists, these - * two generic policies are available: - */ - -#define CPUFREQ_POLICY_POWERSAVE (1) -#define CPUFREQ_POLICY_PERFORMANCE (2) - -/* Frequency values here are CPU kHz so that hardware which doesn't run - * with some frequencies can complain without having to guess what per - * cent / per mille means. +/* + * Frequency values here are CPU kHz + * * Maximum transition latency is in nanoseconds - if it's unknown, * CPUFREQ_ETERNAL shall be used. */ +#define CPUFREQ_ETERNAL (-1) +#define CPUFREQ_NAME_LEN 16 +/* Print length for names. Extra 1 space for accomodating '\n' in prints */ +#define CPUFREQ_NAME_PLEN (CPUFREQ_NAME_LEN + 1) + struct cpufreq_governor; -/* /sys/devices/system/cpu/cpufreq: entry point for global variables */ -extern struct kobject *cpufreq_global_kobject; +struct cpufreq_freqs { + unsigned int cpu; /* cpu nr */ + unsigned int old; + unsigned int new; + u8 flags; /* flags of cpufreq_driver, see below. */ +}; -#define CPUFREQ_ETERNAL (-1) struct cpufreq_cpuinfo { unsigned int max_freq; unsigned int min_freq; @@ -106,129 +74,119 @@ struct cpufreq_policy { * governors are used */ unsigned int policy; /* see above */ struct cpufreq_governor *governor; /* see below */ + void *governor_data; + bool governor_enabled; /* governor start/stop flag */ struct work_struct update; /* if update_policy() needs to be * called, but you're in IRQ context */ struct cpufreq_real_policy user_policy; + struct list_head policy_list; struct kobject kobj; struct completion kobj_unregister; }; -#define CPUFREQ_ADJUST (0) -#define CPUFREQ_INCOMPATIBLE (1) -#define CPUFREQ_NOTIFY (2) -#define CPUFREQ_START (3) -#define CPUFREQ_UPDATE_POLICY_CPU (4) - /* Only for ACPI */ #define CPUFREQ_SHARED_TYPE_NONE (0) /* None */ #define CPUFREQ_SHARED_TYPE_HW (1) /* HW does needed coordination */ #define CPUFREQ_SHARED_TYPE_ALL (2) /* All dependent CPUs should set freq */ #define CPUFREQ_SHARED_TYPE_ANY (3) /* Freq can be set from any dependent CPU*/ +struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu); +void cpufreq_cpu_put(struct cpufreq_policy *policy); + static inline bool policy_is_shared(struct cpufreq_policy *policy) { return cpumask_weight(policy->cpus) > 1; } -/******************** cpufreq transition notifiers *******************/ - -#define CPUFREQ_PRECHANGE (0) -#define CPUFREQ_POSTCHANGE (1) -#define CPUFREQ_RESUMECHANGE (8) -#define CPUFREQ_SUSPENDCHANGE (9) - -struct cpufreq_freqs { - unsigned int cpu; /* cpu nr */ - unsigned int old; - unsigned int new; - u8 flags; /* flags of cpufreq_driver, see below. */ -}; +/* /sys/devices/system/cpu/cpufreq: entry point for global variables */ +extern struct kobject *cpufreq_global_kobject; +int cpufreq_get_global_kobject(void); +void cpufreq_put_global_kobject(void); +int cpufreq_sysfs_create_file(const struct attribute *attr); +void cpufreq_sysfs_remove_file(const struct attribute *attr); +#ifdef CONFIG_CPU_FREQ +unsigned int cpufreq_get(unsigned int cpu); +unsigned int cpufreq_quick_get(unsigned int cpu); +unsigned int cpufreq_quick_get_max(unsigned int cpu); +void disable_cpufreq(void); -/** - * cpufreq_scale - "old * mult / div" calculation for large values (32-bit-arch safe) - * @old: old value - * @div: divisor - * @mult: multiplier - * - * - * new = old * mult / div - */ -static inline unsigned long cpufreq_scale(unsigned long old, u_int div, u_int mult) +u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy); +int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu); +int cpufreq_update_policy(unsigned int cpu); +bool have_governor_per_policy(void); +struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy); +#else +static inline unsigned int cpufreq_get(unsigned int cpu) { -#if BITS_PER_LONG == 32 - - u64 result = ((u64) old) * ((u64) mult); - do_div(result, div); - return (unsigned long) result; - -#elif BITS_PER_LONG == 64 - - unsigned long result = old * ((u64) mult); - result /= div; - return result; - + return 0; +} +static inline unsigned int cpufreq_quick_get(unsigned int cpu) +{ + return 0; +} +static inline unsigned int cpufreq_quick_get_max(unsigned int cpu) +{ + return 0; +} +static inline void disable_cpufreq(void) { } #endif -}; /********************************************************************* - * CPUFREQ GOVERNORS * + * CPUFREQ DRIVER INTERFACE * *********************************************************************/ -#define CPUFREQ_GOV_START 1 -#define CPUFREQ_GOV_STOP 2 -#define CPUFREQ_GOV_LIMITS 3 +#define CPUFREQ_RELATION_L 0 /* lowest frequency at or above target */ +#define CPUFREQ_RELATION_H 1 /* highest frequency below or at target */ -struct cpufreq_governor { - char name[CPUFREQ_NAME_LEN]; - int initialized; - int (*governor) (struct cpufreq_policy *policy, - unsigned int event); - ssize_t (*show_setspeed) (struct cpufreq_policy *policy, - char *buf); - int (*store_setspeed) (struct cpufreq_policy *policy, - unsigned int freq); - unsigned int max_transition_latency; /* HW must be able to switch to - next freq faster than this value in nano secs or we - will fallback to performance governor */ - struct list_head governor_list; - struct module *owner; +struct freq_attr { + struct attribute attr; + ssize_t (*show)(struct cpufreq_policy *, char *); + ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count); }; -/* - * Pass a target to the cpufreq driver. - */ -extern int cpufreq_driver_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation); -extern int __cpufreq_driver_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation); - +#define cpufreq_freq_attr_ro(_name) \ +static struct freq_attr _name = \ +__ATTR(_name, 0444, show_##_name, NULL) -extern int __cpufreq_driver_getavg(struct cpufreq_policy *policy, - unsigned int cpu); +#define cpufreq_freq_attr_ro_perm(_name, _perm) \ +static struct freq_attr _name = \ +__ATTR(_name, _perm, show_##_name, NULL) -int cpufreq_register_governor(struct cpufreq_governor *governor); -void cpufreq_unregister_governor(struct cpufreq_governor *governor); +#define cpufreq_freq_attr_rw(_name) \ +static struct freq_attr _name = \ +__ATTR(_name, 0644, show_##_name, store_##_name) +struct global_attr { + struct attribute attr; + ssize_t (*show)(struct kobject *kobj, + struct attribute *attr, char *buf); + ssize_t (*store)(struct kobject *a, struct attribute *b, + const char *c, size_t count); +}; -/********************************************************************* - * CPUFREQ DRIVER INTERFACE * - *********************************************************************/ +#define define_one_global_ro(_name) \ +static struct global_attr _name = \ +__ATTR(_name, 0444, show_##_name, NULL) -#define CPUFREQ_RELATION_L 0 /* lowest frequency at or above target */ -#define CPUFREQ_RELATION_H 1 /* highest frequency below or at target */ +#define define_one_global_rw(_name) \ +static struct global_attr _name = \ +__ATTR(_name, 0644, show_##_name, store_##_name) -struct freq_attr; struct cpufreq_driver { - struct module *owner; char name[CPUFREQ_NAME_LEN]; u8 flags; + /* + * This should be set by platforms having multiple clock-domains, i.e. + * supporting multiple policies. With this sysfs directories of governor + * would be created in cpu/cpu<num>/cpufreq/ directory and so they can + * use the same governor with different tunables for different clusters. + */ + bool have_governor_per_policy; /* needed by all drivers */ int (*init) (struct cpufreq_policy *policy); @@ -244,8 +202,6 @@ struct cpufreq_driver { unsigned int (*get) (unsigned int cpu); /* optional */ - unsigned int (*getavg) (struct cpufreq_policy *policy, - unsigned int cpu); int (*bios_limit) (int cpu, unsigned int *limit); int (*exit) (struct cpufreq_policy *policy); @@ -255,7 +211,6 @@ struct cpufreq_driver { }; /* flags */ - #define CPUFREQ_STICKY 0x01 /* the driver isn't removed even if * all ->init() calls failed */ #define CPUFREQ_CONST_LOOPS 0x02 /* loops_per_jiffy or other kernel @@ -267,11 +222,10 @@ struct cpufreq_driver { int cpufreq_register_driver(struct cpufreq_driver *driver_data); int cpufreq_unregister_driver(struct cpufreq_driver *driver_data); +const char *cpufreq_get_current_driver(void); -void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state); - - -static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, unsigned int min, unsigned int max) +static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, + unsigned int min, unsigned int max) { if (policy->min < min) policy->min = min; @@ -286,85 +240,121 @@ static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, u return; } -struct freq_attr { - struct attribute attr; - ssize_t (*show)(struct cpufreq_policy *, char *); - ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count); -}; - -#define cpufreq_freq_attr_ro(_name) \ -static struct freq_attr _name = \ -__ATTR(_name, 0444, show_##_name, NULL) - -#define cpufreq_freq_attr_ro_perm(_name, _perm) \ -static struct freq_attr _name = \ -__ATTR(_name, _perm, show_##_name, NULL) - -#define cpufreq_freq_attr_rw(_name) \ -static struct freq_attr _name = \ -__ATTR(_name, 0644, show_##_name, store_##_name) +/********************************************************************* + * CPUFREQ NOTIFIER INTERFACE * + *********************************************************************/ -struct global_attr { - struct attribute attr; - ssize_t (*show)(struct kobject *kobj, - struct attribute *attr, char *buf); - ssize_t (*store)(struct kobject *a, struct attribute *b, - const char *c, size_t count); -}; +#define CPUFREQ_TRANSITION_NOTIFIER (0) +#define CPUFREQ_POLICY_NOTIFIER (1) -#define define_one_global_ro(_name) \ -static struct global_attr _name = \ -__ATTR(_name, 0444, show_##_name, NULL) +/* Transition notifiers */ +#define CPUFREQ_PRECHANGE (0) +#define CPUFREQ_POSTCHANGE (1) +#define CPUFREQ_RESUMECHANGE (8) +#define CPUFREQ_SUSPENDCHANGE (9) -#define define_one_global_rw(_name) \ -static struct global_attr _name = \ -__ATTR(_name, 0644, show_##_name, store_##_name) +/* Policy Notifiers */ +#define CPUFREQ_ADJUST (0) +#define CPUFREQ_INCOMPATIBLE (1) +#define CPUFREQ_NOTIFY (2) +#define CPUFREQ_START (3) +#define CPUFREQ_UPDATE_POLICY_CPU (4) -struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu); -void cpufreq_cpu_put(struct cpufreq_policy *data); -const char *cpufreq_get_current_driver(void); +#ifdef CONFIG_CPU_FREQ +int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); +int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); -/********************************************************************* - * CPUFREQ 2.6. INTERFACE * - *********************************************************************/ -int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu); -int cpufreq_update_policy(unsigned int cpu); +void cpufreq_notify_transition(struct cpufreq_policy *policy, + struct cpufreq_freqs *freqs, unsigned int state); -#ifdef CONFIG_CPU_FREQ -/* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */ -unsigned int cpufreq_get(unsigned int cpu); -#else -static inline unsigned int cpufreq_get(unsigned int cpu) +#else /* CONFIG_CPU_FREQ */ +static inline int cpufreq_register_notifier(struct notifier_block *nb, + unsigned int list) { return 0; } -#endif - -/* query the last known CPU freq (in kHz). If zero, cpufreq couldn't detect it */ -#ifdef CONFIG_CPU_FREQ -unsigned int cpufreq_quick_get(unsigned int cpu); -unsigned int cpufreq_quick_get_max(unsigned int cpu); -#else -static inline unsigned int cpufreq_quick_get(unsigned int cpu) +static inline int cpufreq_unregister_notifier(struct notifier_block *nb, + unsigned int list) { return 0; } -static inline unsigned int cpufreq_quick_get_max(unsigned int cpu) +#endif /* !CONFIG_CPU_FREQ */ + +/** + * cpufreq_scale - "old * mult / div" calculation for large values (32-bit-arch + * safe) + * @old: old value + * @div: divisor + * @mult: multiplier + * + * + * new = old * mult / div + */ +static inline unsigned long cpufreq_scale(unsigned long old, u_int div, + u_int mult) { - return 0; -} -#endif +#if BITS_PER_LONG == 32 + u64 result = ((u64) old) * ((u64) mult); + do_div(result, div); + return (unsigned long) result; +#elif BITS_PER_LONG == 64 + unsigned long result = old * ((u64) mult); + result /= div; + return result; +#endif +} /********************************************************************* - * CPUFREQ DEFAULT GOVERNOR * + * CPUFREQ GOVERNORS * *********************************************************************/ +/* + * If (cpufreq_driver->target) exists, the ->governor decides what frequency + * within the limits is used. If (cpufreq_driver->setpolicy> exists, these + * two generic policies are available: + */ +#define CPUFREQ_POLICY_POWERSAVE (1) +#define CPUFREQ_POLICY_PERFORMANCE (2) + +/* Governor Events */ +#define CPUFREQ_GOV_START 1 +#define CPUFREQ_GOV_STOP 2 +#define CPUFREQ_GOV_LIMITS 3 +#define CPUFREQ_GOV_POLICY_INIT 4 +#define CPUFREQ_GOV_POLICY_EXIT 5 + +struct cpufreq_governor { + char name[CPUFREQ_NAME_LEN]; + int initialized; + int (*governor) (struct cpufreq_policy *policy, + unsigned int event); + ssize_t (*show_setspeed) (struct cpufreq_policy *policy, + char *buf); + int (*store_setspeed) (struct cpufreq_policy *policy, + unsigned int freq); + unsigned int max_transition_latency; /* HW must be able to switch to + next freq faster than this value in nano secs or we + will fallback to performance governor */ + struct list_head governor_list; + struct module *owner; +}; + +/* Pass a target to the cpufreq driver */ +int cpufreq_driver_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation); +int __cpufreq_driver_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation); +int cpufreq_register_governor(struct cpufreq_governor *governor); +void cpufreq_unregister_governor(struct cpufreq_governor *governor); +/* CPUFREQ DEFAULT GOVERNOR */ /* - Performance governor is fallback governor if any other gov failed to - auto load due latency restrictions -*/ + * Performance governor is fallback governor if any other gov failed to auto + * load due latency restrictions + */ #ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE extern struct cpufreq_governor cpufreq_gov_performance; #endif @@ -384,7 +374,6 @@ extern struct cpufreq_governor cpufreq_gov_conservative; #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_conservative) #endif - /********************************************************************* * FREQUENCY TABLE HELPERS * *********************************************************************/ @@ -393,7 +382,7 @@ extern struct cpufreq_governor cpufreq_gov_conservative; #define CPUFREQ_TABLE_END ~1 struct cpufreq_frequency_table { - unsigned int index; /* any */ + unsigned int driver_data; /* driver specific data, not used by core */ unsigned int frequency; /* kHz - doesn't need to be in ascending * order */ }; @@ -410,15 +399,16 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, unsigned int relation, unsigned int *index); -/* the following 3 funtions are for cpufreq core use only */ +void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy); +ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf); + +/* the following funtion is for cpufreq core use only */ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu); /* the following are really really optional */ extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs; - void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, unsigned int cpu); -void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy); - void cpufreq_frequency_table_put_attr(unsigned int cpu); + #endif /* _LINUX_CPUFREQ_H */ diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 480c14dc1ddd..781addc66f03 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -13,11 +13,9 @@ #include <linux/percpu.h> #include <linux/list.h> -#include <linux/kobject.h> -#include <linux/completion.h> #include <linux/hrtimer.h> -#define CPUIDLE_STATE_MAX 8 +#define CPUIDLE_STATE_MAX 10 #define CPUIDLE_NAME_LEN 16 #define CPUIDLE_DESC_LEN 32 @@ -57,9 +55,14 @@ struct cpuidle_state { /* Idle State Flags */ #define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */ #define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */ +#define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */ #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) +struct cpuidle_device_kobj; +struct cpuidle_state_kobj; +struct cpuidle_driver_kobj; + struct cpuidle_device { unsigned int registered:1; unsigned int enabled:1; @@ -70,9 +73,8 @@ struct cpuidle_device { struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX]; struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; struct cpuidle_driver_kobj *kobj_driver; + struct cpuidle_device_kobj *kobj_dev; struct list_head device_list; - struct kobject kobj; - struct completion kobj_unregister; #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED int safe_state_index; @@ -104,12 +106,15 @@ struct cpuidle_driver { struct module *owner; int refcnt; - /* set to 1 to use the core cpuidle time keeping (for all states). */ - unsigned int en_core_tk_irqen:1; + /* used by the cpuidle framework to setup the broadcast timer */ + unsigned int bctimer:1; /* states array must be ordered in decreasing power consumption */ struct cpuidle_state states[CPUIDLE_STATE_MAX]; int state_count; int safe_state_index; + + /* the driver handles the cpus in cpumask */ + struct cpumask *cpumask; }; #ifdef CONFIG_CPU_IDLE @@ -122,23 +127,18 @@ extern void cpuidle_driver_unref(void); extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); extern int cpuidle_register_device(struct cpuidle_device *dev); extern void cpuidle_unregister_device(struct cpuidle_device *dev); - +extern int cpuidle_register(struct cpuidle_driver *drv, + const struct cpumask *const coupled_cpus); +extern void cpuidle_unregister(struct cpuidle_driver *drv); extern void cpuidle_pause_and_lock(void); extern void cpuidle_resume_and_unlock(void); extern void cpuidle_pause(void); extern void cpuidle_resume(void); extern int cpuidle_enable_device(struct cpuidle_device *dev); extern void cpuidle_disable_device(struct cpuidle_device *dev); -extern int cpuidle_wrap_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index, - int (*enter)(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index)); extern int cpuidle_play_dead(void); extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev); -extern int cpuidle_register_cpu_driver(struct cpuidle_driver *drv, int cpu); -extern void cpuidle_unregister_cpu_driver(struct cpuidle_driver *drv, int cpu); - #else static inline void disable_cpuidle(void) { } static inline int cpuidle_idle_call(void) { return -ENODEV; } @@ -151,7 +151,10 @@ static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } static inline int cpuidle_register_device(struct cpuidle_device *dev) {return -ENODEV; } static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { } - +static inline int cpuidle_register(struct cpuidle_driver *drv, + const struct cpumask *const coupled_cpus) +{return -ENODEV; } +static inline void cpuidle_unregister(struct cpuidle_driver *drv) { } static inline void cpuidle_pause_and_lock(void) { } static inline void cpuidle_resume_and_unlock(void) { } static inline void cpuidle_pause(void) { } @@ -159,11 +162,6 @@ static inline void cpuidle_resume(void) { } static inline int cpuidle_enable_device(struct cpuidle_device *dev) {return -ENODEV; } static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } -static inline int cpuidle_wrap_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index, - int (*enter)(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index)) -{ return -ENODEV; } static inline int cpuidle_play_dead(void) {return -ENODEV; } #endif diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 032560295fcb..d08e4d2a9b92 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -591,6 +591,21 @@ static inline int cpulist_scnprintf(char *buf, int len, } /** + * cpumask_parse - extract a cpumask from from a string + * @buf: the buffer to extract from + * @dstp: the cpumask to set. + * + * Returns -errno, or 0 for success. + */ +static inline int cpumask_parse(const char *buf, struct cpumask *dstp) +{ + char *nl = strchr(buf, '\n'); + int len = nl ? nl - buf : strlen(buf); + + return bitmap_parse(buf, len, cpumask_bits(dstp), nr_cpumask_bits); +} + +/** * cpulist_parse - extract a cpumask from a user string of ranges * @buf: the buffer to extract from * @dstp: the cpumask to set. diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index 8c8a60d29407..cc1b01cf2035 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -11,7 +11,6 @@ #include <linux/sched.h> #include <linux/cpumask.h> #include <linux/nodemask.h> -#include <linux/cgroup.h> #include <linux/mm.h> #ifdef CONFIG_CPUSETS @@ -64,10 +63,9 @@ extern int cpuset_mems_allowed_intersects(const struct task_struct *tsk1, extern int cpuset_memory_pressure_enabled; extern void __cpuset_memory_pressure_bump(void); -extern const struct file_operations proc_cpuset_operations; -struct seq_file; extern void cpuset_task_status_allowed(struct seq_file *m, struct task_struct *task); +extern int proc_cpuset_show(struct seq_file *, void *); extern int cpuset_mem_spread_node(void); extern int cpuset_slab_spread_node(void); diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index 37e4f8da7cdf..fe68a5a98583 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -12,6 +12,15 @@ extern unsigned long long elfcorehdr_addr; extern unsigned long long elfcorehdr_size; +extern int __weak elfcorehdr_alloc(unsigned long long *addr, + unsigned long long *size); +extern void __weak elfcorehdr_free(unsigned long long addr); +extern ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos); +extern ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos); +extern int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma, + unsigned long from, unsigned long pfn, + unsigned long size, pgprot_t prot); + extern ssize_t copy_oldmem_page(unsigned long, char *, size_t, unsigned long, int); diff --git a/include/linux/crc-t10dif.h b/include/linux/crc-t10dif.h index a9c96d865ee7..b3cb71f0d3b0 100644 --- a/include/linux/crc-t10dif.h +++ b/include/linux/crc-t10dif.h @@ -3,6 +3,10 @@ #include <linux/types.h> +#define CRC_T10DIF_DIGEST_SIZE 2 +#define CRC_T10DIF_BLOCK_SIZE 1 + +__u16 crc_t10dif_generic(__u16 crc, const unsigned char *buffer, size_t len); __u16 crc_t10dif(unsigned char const *, size_t); #endif diff --git a/include/linux/ctype.h b/include/linux/ctype.h index 8acfe312f947..653589e3e30e 100644 --- a/include/linux/ctype.h +++ b/include/linux/ctype.h @@ -61,4 +61,10 @@ static inline char _tolower(const char c) return c | 0x20; } +/* Fast check for octal digit */ +static inline int isodigit(const char c) +{ + return c >= '0' && c <= '7'; +} + #endif diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 1a6bb81f0fe5..716c3760ee39 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -9,6 +9,7 @@ #include <linux/seqlock.h> #include <linux/cache.h> #include <linux/rcupdate.h> +#include <linux/lockref.h> struct nameidata; struct path; @@ -54,11 +55,11 @@ struct qstr { #define hashlen_len(hashlen) ((u32)((hashlen) >> 32)) struct dentry_stat_t { - int nr_dentry; - int nr_unused; - int age_limit; /* age in seconds */ - int want_pages; /* pages requested by system */ - int dummy[2]; + long nr_dentry; + long nr_unused; + long age_limit; /* age in seconds */ + long want_pages; /* pages requested by system */ + long dummy[2]; }; extern struct dentry_stat_t dentry_stat; @@ -100,6 +101,8 @@ extern unsigned int full_name_hash(const unsigned char *, unsigned int); # endif #endif +#define d_lock d_lockref.lock + struct dentry { /* RCU lookup touched fields */ unsigned int d_flags; /* protected by d_lock */ @@ -112,8 +115,7 @@ struct dentry { unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */ /* Ref lookup also touches following */ - unsigned int d_count; /* protected by d_lock */ - spinlock_t d_lock; /* per dentry lock */ + struct lockref d_lockref; /* per-dentry lock and refcount */ const struct dentry_operations *d_op; struct super_block *d_sb; /* The root of the dentry tree */ unsigned long d_time; /* used by d_revalidate */ @@ -146,10 +148,8 @@ enum dentry_d_lock_class struct dentry_operations { int (*d_revalidate)(struct dentry *, unsigned int); int (*d_weak_revalidate)(struct dentry *, unsigned int); - int (*d_hash)(const struct dentry *, const struct inode *, - struct qstr *); - int (*d_compare)(const struct dentry *, const struct inode *, - const struct dentry *, const struct inode *, + int (*d_hash)(const struct dentry *, struct qstr *); + int (*d_compare)(const struct dentry *, const struct dentry *, unsigned int, const char *, const struct qstr *); int (*d_delete)(const struct dentry *); void (*d_release)(struct dentry *); @@ -208,11 +208,12 @@ struct dentry_operations { #define DCACHE_MANAGED_DENTRY \ (DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT) +#define DCACHE_LRU_LIST 0x80000 #define DCACHE_DENTRY_KILLED 0x100000 extern seqlock_t rename_lock; -static inline int dname_external(struct dentry *dentry) +static inline int dname_external(const struct dentry *dentry) { return dentry->d_name.name != dentry->d_iname; } @@ -223,6 +224,7 @@ static inline int dname_external(struct dentry *dentry) extern void d_instantiate(struct dentry *, struct inode *); extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *); extern struct dentry * d_materialise_unique(struct dentry *, struct inode *); +extern int d_instantiate_no_diralias(struct dentry *, struct inode *); extern void __d_drop(struct dentry *dentry); extern void d_drop(struct dentry *dentry); extern void d_delete(struct dentry *); @@ -246,11 +248,14 @@ extern struct dentry * d_make_root(struct inode *); /* <clickety>-<click> the ramfs-type tree */ extern void d_genocide(struct dentry *); +extern void d_tmpfile(struct dentry *, struct inode *); + extern struct dentry *d_find_alias(struct inode *); extern void d_prune_aliases(struct inode *); /* test whether we have any submounts in a subdir tree */ extern int have_submounts(struct dentry *); +extern int check_submounts_and_drop(struct dentry *); /* * This adds the entry to the hash queues. @@ -300,29 +305,11 @@ extern struct dentry *d_lookup(const struct dentry *, const struct qstr *); extern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *); extern struct dentry *__d_lookup(const struct dentry *, const struct qstr *); extern struct dentry *__d_lookup_rcu(const struct dentry *parent, - const struct qstr *name, - unsigned *seq, struct inode *inode); + const struct qstr *name, unsigned *seq); -/** - * __d_rcu_to_refcount - take a refcount on dentry if sequence check is ok - * @dentry: dentry to take a ref on - * @seq: seqcount to verify against - * Returns: 0 on failure, else 1. - * - * __d_rcu_to_refcount operates on a dentry,seq pair that was returned - * by __d_lookup_rcu, to get a reference on an rcu-walk dentry. - */ -static inline int __d_rcu_to_refcount(struct dentry *dentry, unsigned seq) +static inline unsigned d_count(const struct dentry *dentry) { - int ret = 0; - - assert_spin_locked(&dentry->d_lock); - if (!read_seqcount_retry(&dentry->d_seq, seq)) { - ret = 1; - dentry->d_count++; - } - - return ret; + return dentry->d_lockref.count; } /* validate "insecure" dentry pointer */ @@ -332,6 +319,7 @@ extern int d_validate(struct dentry *, struct dentry *); * helper function for dentry_operations.d_dname() members */ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); +extern char *simple_dname(struct dentry *, char *, int); extern char *__d_path(const struct path *, const struct path *, char *, int); extern char *d_absolute_path(const struct path *, char *, int); @@ -352,17 +340,14 @@ extern char *dentry_path(struct dentry *, char *, int); static inline struct dentry *dget_dlock(struct dentry *dentry) { if (dentry) - dentry->d_count++; + dentry->d_lockref.count++; return dentry; } static inline struct dentry *dget(struct dentry *dentry) { - if (dentry) { - spin_lock(&dentry->d_lock); - dget_dlock(dentry); - spin_unlock(&dentry->d_lock); - } + if (dentry) + lockref_get(&dentry->d_lockref); return dentry; } @@ -375,17 +360,17 @@ extern struct dentry *dget_parent(struct dentry *dentry); * Returns true if the dentry passed is not currently hashed. */ -static inline int d_unhashed(struct dentry *dentry) +static inline int d_unhashed(const struct dentry *dentry) { return hlist_bl_unhashed(&dentry->d_hash); } -static inline int d_unlinked(struct dentry *dentry) +static inline int d_unlinked(const struct dentry *dentry) { return d_unhashed(dentry) && !IS_ROOT(dentry); } -static inline int cant_mount(struct dentry *dentry) +static inline int cant_mount(const struct dentry *dentry) { return (dentry->d_flags & DCACHE_CANT_MOUNT); } @@ -399,16 +384,20 @@ static inline void dont_mount(struct dentry *dentry) extern void dput(struct dentry *); -static inline bool d_managed(struct dentry *dentry) +static inline bool d_managed(const struct dentry *dentry) { return dentry->d_flags & DCACHE_MANAGED_DENTRY; } -static inline bool d_mountpoint(struct dentry *dentry) +static inline bool d_mountpoint(const struct dentry *dentry) { return dentry->d_flags & DCACHE_MOUNTED; } extern int sysctl_vfs_cache_pressure; +static inline unsigned long vfs_pressure_ratio(unsigned long val) +{ + return mult_frac(val, sysctl_vfs_cache_pressure, 100); +} #endif /* __LINUX_DCACHE_H */ diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h index a975de1ff59f..822c1354f3a6 100644 --- a/include/linux/debug_locks.h +++ b/include/linux/debug_locks.h @@ -27,7 +27,7 @@ extern int debug_locks_off(void); \ if (!oops_in_progress && unlikely(c)) { \ if (debug_locks_off() && !debug_locks_silent) \ - WARN_ON(1); \ + WARN(1, "DEBUG_LOCKS_WARN_ON(%s)", #c); \ __ret = 1; \ } \ __ret; \ diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index 63f2465807d4..263489d0788d 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -79,6 +79,8 @@ struct dentry *debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, u64 *value); struct dentry *debugfs_create_size_t(const char *name, umode_t mode, struct dentry *parent, size_t *value); +struct dentry *debugfs_create_atomic_t(const char *name, umode_t mode, + struct dentry *parent, atomic_t *value); struct dentry *debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent, u32 *value); @@ -190,6 +192,13 @@ static inline struct dentry *debugfs_create_x32(const char *name, umode_t mode, return ERR_PTR(-ENODEV); } +static inline struct dentry *debugfs_create_x64(const char *name, umode_t mode, + struct dentry *parent, + u64 *value) +{ + return ERR_PTR(-ENODEV); +} + static inline struct dentry *debugfs_create_size_t(const char *name, umode_t mode, struct dentry *parent, size_t *value) diff --git a/include/linux/debugobjects.h b/include/linux/debugobjects.h index 0e5f5785d9f2..98ffcbd4888e 100644 --- a/include/linux/debugobjects.h +++ b/include/linux/debugobjects.h @@ -63,7 +63,7 @@ struct debug_obj_descr { extern void debug_object_init (void *addr, struct debug_obj_descr *descr); extern void debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr); -extern void debug_object_activate (void *addr, struct debug_obj_descr *descr); +extern int debug_object_activate (void *addr, struct debug_obj_descr *descr); extern void debug_object_deactivate(void *addr, struct debug_obj_descr *descr); extern void debug_object_destroy (void *addr, struct debug_obj_descr *descr); extern void debug_object_free (void *addr, struct debug_obj_descr *descr); @@ -85,8 +85,8 @@ static inline void debug_object_init (void *addr, struct debug_obj_descr *descr) { } static inline void debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr) { } -static inline void -debug_object_activate (void *addr, struct debug_obj_descr *descr) { } +static inline int +debug_object_activate (void *addr, struct debug_obj_descr *descr) { return 0; } static inline void debug_object_deactivate(void *addr, struct debug_obj_descr *descr) { } static inline void diff --git a/include/linux/decompress/unlz4.h b/include/linux/decompress/unlz4.h new file mode 100644 index 000000000000..d5b68bf3ec92 --- /dev/null +++ b/include/linux/decompress/unlz4.h @@ -0,0 +1,10 @@ +#ifndef DECOMPRESS_UNLZ4_H +#define DECOMPRESS_UNLZ4_H + +int unlz4(unsigned char *inbuf, int len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, + int *pos, + void(*error)(char *x)); +#endif diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index e83ef39b3bea..5f1ab92107e6 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -181,6 +181,8 @@ extern struct devfreq *devfreq_add_device(struct device *dev, const char *governor_name, void *data); extern int devfreq_remove_device(struct devfreq *devfreq); + +/* Supposed to be called by PM_SLEEP/PM_RUNTIME callbacks */ extern int devfreq_suspend_device(struct devfreq *devfreq); extern int devfreq_resume_device(struct devfreq *devfreq); @@ -213,7 +215,7 @@ struct devfreq_simple_ondemand_data { #endif #else /* !CONFIG_PM_DEVFREQ */ -static struct devfreq *devfreq_add_device(struct device *dev, +static inline struct devfreq *devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile, const char *governor_name, void *data) @@ -221,34 +223,34 @@ static struct devfreq *devfreq_add_device(struct device *dev, return NULL; } -static int devfreq_remove_device(struct devfreq *devfreq) +static inline int devfreq_remove_device(struct devfreq *devfreq) { return 0; } -static int devfreq_suspend_device(struct devfreq *devfreq) +static inline int devfreq_suspend_device(struct devfreq *devfreq) { return 0; } -static int devfreq_resume_device(struct devfreq *devfreq) +static inline int devfreq_resume_device(struct devfreq *devfreq) { return 0; } -static struct opp *devfreq_recommended_opp(struct device *dev, +static inline struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { - return -EINVAL; + return ERR_PTR(-EINVAL); } -static int devfreq_register_opp_notifier(struct device *dev, +static inline int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq) { return -EINVAL; } -static int devfreq_unregister_opp_notifier(struct device *dev, +static inline int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq) { return -EINVAL; diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 1e483fa7afb4..ed419c62dde1 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -10,6 +10,7 @@ #include <linux/bio.h> #include <linux/blkdev.h> +#include <linux/math64.h> #include <linux/ratelimit.h> struct dm_dev; @@ -79,11 +80,26 @@ typedef int (*dm_ioctl_fn) (struct dm_target *ti, unsigned int cmd, typedef int (*dm_merge_fn) (struct dm_target *ti, struct bvec_merge_data *bvm, struct bio_vec *biovec, int max_size); +/* + * These iteration functions are typically used to check (and combine) + * properties of underlying devices. + * E.g. Does at least one underlying device support flush? + * Does any underlying device not support WRITE_SAME? + * + * The callout function is called once for each contiguous section of + * an underlying device. State can be maintained in *data. + * Return non-zero to stop iterating through any further devices. + */ typedef int (*iterate_devices_callout_fn) (struct dm_target *ti, struct dm_dev *dev, sector_t start, sector_t len, void *data); +/* + * This function must iterate through each section of device used by the + * target until it encounters a non-zero return code, which it then returns. + * Returns zero if no callout returned non-zero. + */ typedef int (*dm_iterate_devices_fn) (struct dm_target *ti, iterate_devices_callout_fn fn, void *data); @@ -390,13 +406,14 @@ int dm_noflush_suspending(struct dm_target *ti); union map_info *dm_get_mapinfo(struct bio *bio); union map_info *dm_get_rq_mapinfo(struct request *rq); +struct queue_limits *dm_get_queue_limits(struct mapped_device *md); + /* * Geometry functions. */ int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo); int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo); - /*----------------------------------------------------------------- * Functions for manipulating device-mapper tables. *---------------------------------------------------------------*/ @@ -431,9 +448,9 @@ int __must_check dm_set_target_max_io_len(struct dm_target *ti, sector_t len); /* * Table reference counting. */ -struct dm_table *dm_get_live_table(struct mapped_device *md); -void dm_table_get(struct dm_table *t); -void dm_table_put(struct dm_table *t); +struct dm_table *dm_get_live_table(struct mapped_device *md, int *srcu_idx); +void dm_put_live_table(struct mapped_device *md, int srcu_idx); +void dm_sync_table(struct mapped_device *md); /* * Queries @@ -535,6 +552,14 @@ extern struct ratelimit_state dm_ratelimit_state; #define DM_MAPIO_REMAPPED 1 #define DM_MAPIO_REQUEUE DM_ENDIO_REQUEUE +#define dm_sector_div64(x, y)( \ +{ \ + u64 _res; \ + (x) = div64_u64_rem(x, y, &_res); \ + _res; \ +} \ +) + /* * Ceiling(n / sz) */ diff --git a/include/linux/device.h b/include/linux/device.h index 9d6464ea99c6..ce690ea34547 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -25,6 +25,7 @@ #include <linux/pm.h> #include <linux/atomic.h> #include <linux/ratelimit.h> +#include <linux/uidgid.h> #include <asm/device.h> struct device; @@ -46,7 +47,11 @@ struct bus_attribute { }; #define BUS_ATTR(_name, _mode, _show, _store) \ -struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store) + struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store) +#define BUS_ATTR_RW(_name) \ + struct bus_attribute bus_attr_##_name = __ATTR_RW(_name) +#define BUS_ATTR_RO(_name) \ + struct bus_attribute bus_attr_##_name = __ATTR_RO(_name) extern int __must_check bus_create_file(struct bus_type *, struct bus_attribute *); @@ -61,6 +66,9 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); * @bus_attrs: Default attributes of the bus. * @dev_attrs: Default attributes of the devices on the bus. * @drv_attrs: Default attributes of the device drivers on the bus. + * @bus_groups: Default attributes of the bus. + * @dev_groups: Default attributes of the devices on the bus. + * @drv_groups: Default attributes of the device drivers on the bus. * @match: Called, perhaps multiple times, whenever a new device or driver * is added for this bus. It should return a nonzero value if the * given device can be handled by the given driver. @@ -70,6 +78,10 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); * the specific driver's probe to initial the matched device. * @remove: Called when a device removed from this bus. * @shutdown: Called at shut-down time to quiesce the device. + * + * @online: Called to put the device back online (after offlining it). + * @offline: Called to put the device offline for hot-removal. May fail. + * * @suspend: Called when a device on this bus wants to go to sleep mode. * @resume: Called to bring a device on this bus out of sleep mode. * @pm: Power management operations of this bus, callback the specific @@ -79,6 +91,7 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); * bus-specific setup * @p: The private data of the driver core, only the driver core can * touch this. + * @lock_key: Lock class key for use by the lock validator * * A bus is a channel between the processor and one or more devices. For the * purposes of the device model, all devices are connected via a bus, even if @@ -93,9 +106,12 @@ struct bus_type { const char *name; const char *dev_name; struct device *dev_root; - struct bus_attribute *bus_attrs; - struct device_attribute *dev_attrs; - struct driver_attribute *drv_attrs; + struct bus_attribute *bus_attrs; /* use bus_groups instead */ + struct device_attribute *dev_attrs; /* use dev_groups instead */ + struct driver_attribute *drv_attrs; /* use drv_groups instead */ + const struct attribute_group **bus_groups; + const struct attribute_group **dev_groups; + const struct attribute_group **drv_groups; int (*match)(struct device *dev, struct device_driver *drv); int (*uevent)(struct device *dev, struct kobj_uevent_env *env); @@ -103,6 +119,9 @@ struct bus_type { int (*remove)(struct device *dev); void (*shutdown)(struct device *dev); + int (*online)(struct device *dev); + int (*offline)(struct device *dev); + int (*suspend)(struct device *dev, pm_message_t state); int (*resume)(struct device *dev); @@ -111,17 +130,11 @@ struct bus_type { struct iommu_ops *iommu_ops; struct subsys_private *p; + struct lock_class_key lock_key; }; -/* This is a #define to keep the compiler from merging different - * instances of the __key variable */ -#define bus_register(subsys) \ -({ \ - static struct lock_class_key __key; \ - __bus_register(subsys, &__key); \ -}) -extern int __must_check __bus_register(struct bus_type *bus, - struct lock_class_key *key); +extern int __must_check bus_register(struct bus_type *bus); + extern void bus_unregister(struct bus_type *bus); extern int __must_check bus_rescan_devices(struct bus_type *bus); @@ -258,9 +271,14 @@ struct driver_attribute { size_t count); }; -#define DRIVER_ATTR(_name, _mode, _show, _store) \ -struct driver_attribute driver_attr_##_name = \ - __ATTR(_name, _mode, _show, _store) +#define DRIVER_ATTR(_name, _mode, _show, _store) \ + struct driver_attribute driver_attr_##_name = __ATTR(_name, _mode, _show, _store) +#define DRIVER_ATTR_RW(_name) \ + struct driver_attribute driver_attr_##_name = __ATTR_RW(_name) +#define DRIVER_ATTR_RO(_name) \ + struct driver_attribute driver_attr_##_name = __ATTR_RO(_name) +#define DRIVER_ATTR_WO(_name) \ + struct driver_attribute driver_attr_##_name = __ATTR_WO(_name) extern int __must_check driver_create_file(struct device_driver *driver, const struct driver_attribute *attr); @@ -302,12 +320,15 @@ void subsys_interface_unregister(struct subsys_interface *sif); int subsys_system_register(struct bus_type *subsys, const struct attribute_group **groups); +int subsys_virtual_register(struct bus_type *subsys, + const struct attribute_group **groups); /** * struct class - device classes * @name: Name of the class. * @owner: The module owner. * @class_attrs: Default attributes of this class. + * @dev_groups: Default attributes of the devices that belong to the class. * @dev_attrs: Default attributes of the devices belong to the class. * @dev_bin_attrs: Default binary attributes of the devices belong to the class. * @dev_kobj: The kobject that represents this class and links it into the hierarchy. @@ -337,7 +358,8 @@ struct class { struct module *owner; struct class_attribute *class_attrs; - struct device_attribute *dev_attrs; + struct device_attribute *dev_attrs; /* use dev_groups instead */ + const struct attribute_group **dev_groups; struct bin_attribute *dev_bin_attrs; struct kobject *dev_kobj; @@ -405,20 +427,35 @@ struct class_attribute { char *buf); ssize_t (*store)(struct class *class, struct class_attribute *attr, const char *buf, size_t count); - const void *(*namespace)(struct class *class, - const struct class_attribute *attr); }; -#define CLASS_ATTR(_name, _mode, _show, _store) \ -struct class_attribute class_attr_##_name = __ATTR(_name, _mode, _show, _store) +#define CLASS_ATTR(_name, _mode, _show, _store) \ + struct class_attribute class_attr_##_name = __ATTR(_name, _mode, _show, _store) +#define CLASS_ATTR_RW(_name) \ + struct class_attribute class_attr_##_name = __ATTR_RW(_name) +#define CLASS_ATTR_RO(_name) \ + struct class_attribute class_attr_##_name = __ATTR_RO(_name) + +extern int __must_check class_create_file_ns(struct class *class, + const struct class_attribute *attr, + const void *ns); +extern void class_remove_file_ns(struct class *class, + const struct class_attribute *attr, + const void *ns); + +static inline int __must_check class_create_file(struct class *class, + const struct class_attribute *attr) +{ + return class_create_file_ns(class, attr, NULL); +} -extern int __must_check class_create_file(struct class *class, - const struct class_attribute *attr); -extern void class_remove_file(struct class *class, - const struct class_attribute *attr); +static inline void class_remove_file(struct class *class, + const struct class_attribute *attr) +{ + return class_remove_file_ns(class, attr, NULL); +} /* Simple class attribute that is just a static string */ - struct class_attribute_string { struct class_attribute attr; char *str; @@ -471,7 +508,8 @@ struct device_type { const char *name; const struct attribute_group **groups; int (*uevent)(struct device *dev, struct kobj_uevent_env *env); - char *(*devnode)(struct device *dev, umode_t *mode); + char *(*devnode)(struct device *dev, umode_t *mode, + kuid_t *uid, kgid_t *gid); void (*release)(struct device *dev); const struct dev_pm_ops *pm; @@ -506,6 +544,12 @@ ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, #define DEVICE_ATTR(_name, _mode, _show, _store) \ struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) +#define DEVICE_ATTR_RW(_name) \ + struct device_attribute dev_attr_##_name = __ATTR_RW(_name) +#define DEVICE_ATTR_RO(_name) \ + struct device_attribute dev_attr_##_name = __ATTR_RO(_name) +#define DEVICE_ATTR_WO(_name) \ + struct device_attribute dev_attr_##_name = __ATTR_WO(_name) #define DEVICE_ULONG_ATTR(_name, _mode, _var) \ struct dev_ext_attribute dev_attr_##_name = \ { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } @@ -578,6 +622,10 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); void __iomem *devm_request_and_ioremap(struct device *dev, struct resource *res); +/* allows to add/remove a custom action to devres stack */ +int devm_add_action(struct device *dev, void (*action)(void *), void *data); +void devm_remove_action(struct device *dev, void (*action)(void *), void *data); + struct device_dma_parameters { /* * a low level driver may set these to teach IOMMU code about @@ -633,6 +681,7 @@ struct acpi_dev_node { * segment limitations. * @dma_pools: Dma pools (if dma'ble device). * @dma_mem: Internal for coherent mem override. + * @cma_area: Contiguous memory area for dma allocations * @archdata: For arch-specific additions. * @of_node: Associated device tree node. * @acpi_node: Associated ACPI device node. @@ -646,6 +695,10 @@ struct acpi_dev_node { * @release: Callback to free the device after all references have * gone away. This should be set by the allocator of the * device (i.e. the bus driver that discovered the device). + * @iommu_group: IOMMU group the device belongs to. + * + * @offline_disabled: If set, the device is permanently online. + * @offline: Set after successful invocation of bus type's .offline(). * * At the lowest level, every device in a Linux system is represented by an * instance of struct device. The device structure contains the information @@ -696,7 +749,7 @@ struct device { struct dma_coherent_mem *dma_mem; /* internal for coherent mem override */ -#ifdef CONFIG_CMA +#ifdef CONFIG_DMA_CMA struct cma *cma_area; /* contiguous memory area for dma allocations */ #endif @@ -718,6 +771,9 @@ struct device { void (*release)(struct device *dev); struct iommu_group *iommu_group; + + bool offline_disabled:1; + bool offline:1; }; static inline struct device *kobj_to_dev(struct kobject *kobj) @@ -849,10 +905,21 @@ extern int device_rename(struct device *dev, const char *new_name); extern int device_move(struct device *dev, struct device *new_parent, enum dpm_order dpm_order); extern const char *device_get_devnode(struct device *dev, - umode_t *mode, const char **tmp); + umode_t *mode, kuid_t *uid, kgid_t *gid, + const char **tmp); extern void *dev_get_drvdata(const struct device *dev); extern int dev_set_drvdata(struct device *dev, void *data); +static inline bool device_supports_offline(struct device *dev) +{ + return dev->bus && dev->bus->offline && dev->bus->online; +} + +extern void lock_device_hotplug(void); +extern void unlock_device_hotplug(void); +extern int lock_device_hotplug_sysfs(void); +extern int device_offline(struct device *dev); +extern int device_online(struct device *dev); /* * Root device objects for grouping under /sys/devices */ @@ -896,6 +963,11 @@ extern __printf(5, 6) struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...); +extern __printf(6, 7) +struct device *device_create_with_groups(struct class *cls, + struct device *parent, dev_t devt, void *drvdata, + const struct attribute_group **groups, + const char *fmt, ...); extern void device_destroy(struct class *cls, dev_t devt); /* @@ -1050,7 +1122,8 @@ do { \ dev_level_ratelimited(dev_notice, dev, fmt, ##__VA_ARGS__) #define dev_info_ratelimited(dev, fmt, ...) \ dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__) -#if defined(CONFIG_DYNAMIC_DEBUG) || defined(DEBUG) +#if defined(CONFIG_DYNAMIC_DEBUG) +/* descriptor check is first to prevent flooding with "callbacks suppressed" */ #define dev_dbg_ratelimited(dev, fmt, ...) \ do { \ static DEFINE_RATELIMIT_STATE(_rs, \ @@ -1059,8 +1132,17 @@ do { \ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \ __ratelimit(&_rs)) \ - __dynamic_pr_debug(&descriptor, pr_fmt(fmt), \ - ##__VA_ARGS__); \ + __dynamic_dev_dbg(&descriptor, dev, fmt, \ + ##__VA_ARGS__); \ +} while (0) +#elif defined(DEBUG) +#define dev_dbg_ratelimited(dev, fmt, ...) \ +do { \ + static DEFINE_RATELIMIT_STATE(_rs, \ + DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + if (__ratelimit(&_rs)) \ + dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \ } while (0) #else #define dev_dbg_ratelimited(dev, fmt, ...) \ diff --git a/include/linux/dm9000.h b/include/linux/dm9000.h index 96e87693d933..841925fbfe8a 100644 --- a/include/linux/dm9000.h +++ b/include/linux/dm9000.h @@ -14,6 +14,8 @@ #ifndef __DM9000_PLATFORM_DATA #define __DM9000_PLATFORM_DATA __FILE__ +#include <linux/if_ether.h> + /* IO control flags */ #define DM9000_PLATF_8BITONLY (0x0001) @@ -27,7 +29,7 @@ struct dm9000_plat_data { unsigned int flags; - unsigned char dev_addr[6]; + unsigned char dev_addr[ETH_ALEN]; /* allow replacement IO routines */ diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 9978b614a1aa..dfac5ed31120 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -112,6 +112,8 @@ struct dma_buf_ops { * @file: file pointer used for sharing buffers across, and for refcounting. * @attachments: list of dma_buf_attachment that denotes all devices attached. * @ops: dma_buf_ops associated with this buffer object. + * @exp_name: name of the exporter; useful for debugging. + * @list_node: node for dma_buf accounting and debugging. * @priv: exporter specific private data for this buffer object. */ struct dma_buf { @@ -123,6 +125,8 @@ struct dma_buf { struct mutex lock; unsigned vmapping_counter; void *vmap_ptr; + const char *exp_name; + struct list_head list_node; void *priv; }; @@ -162,8 +166,13 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, struct device *dev); void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *dmabuf_attach); -struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops, - size_t size, int flags); + +struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops, + size_t size, int flags, const char *); + +#define dma_buf_export(priv, ops, size, flags) \ + dma_buf_export_named(priv, ops, size, flags, __FILE__) + int dma_buf_fd(struct dma_buf *dmabuf, int flags); struct dma_buf *dma_buf_get(int fd); void dma_buf_put(struct dma_buf *dmabuf); @@ -185,5 +194,6 @@ int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, unsigned long); void *dma_buf_vmap(struct dma_buf *); void dma_buf_vunmap(struct dma_buf *, void *vaddr); - +int dma_buf_debugfs_create_file(const char *name, + int (*write)(struct seq_file *)); #endif /* __DMA_BUF_H__ */ diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h index 01b5c84be828..3b28f937d959 100644 --- a/include/linux/dma-contiguous.h +++ b/include/linux/dma-contiguous.h @@ -57,7 +57,7 @@ struct cma; struct page; struct device; -#ifdef CONFIG_CMA +#ifdef CONFIG_DMA_CMA /* * There is always at least global CMA area and a few optional device @@ -67,9 +67,53 @@ struct device; extern struct cma *dma_contiguous_default_area; +static inline struct cma *dev_get_cma_area(struct device *dev) +{ + if (dev && dev->cma_area) + return dev->cma_area; + return dma_contiguous_default_area; +} + +static inline void dev_set_cma_area(struct device *dev, struct cma *cma) +{ + if (dev) + dev->cma_area = cma; +} + +static inline void dma_contiguous_set_default(struct cma *cma) +{ + dma_contiguous_default_area = cma; +} + void dma_contiguous_reserve(phys_addr_t addr_limit); -int dma_declare_contiguous(struct device *dev, phys_addr_t size, - phys_addr_t base, phys_addr_t limit); + +int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, + phys_addr_t limit, struct cma **res_cma); + +/** + * dma_declare_contiguous() - reserve area for contiguous memory handling + * for particular device + * @dev: Pointer to device structure. + * @size: Size of the reserved memory. + * @base: Start address of the reserved memory (optional, 0 for any). + * @limit: End address of the reserved memory (optional, 0 for any). + * + * This function reserves memory for specified device. It should be + * called by board specific code when early allocator (memblock or bootmem) + * is still activate. + */ + +static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size, + phys_addr_t base, phys_addr_t limit) +{ + struct cma *cma; + int ret; + ret = dma_contiguous_reserve_area(size, base, limit, &cma); + if (ret == 0) + dev_set_cma_area(dev, cma); + + return ret; +} struct page *dma_alloc_from_contiguous(struct device *dev, int count, unsigned int order); @@ -80,8 +124,22 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages, #define MAX_CMA_AREAS (0) +static inline struct cma *dev_get_cma_area(struct device *dev) +{ + return NULL; +} + +static inline void dev_set_cma_area(struct device *dev, struct cma *cma) { } + +static inline void dma_contiguous_set_default(struct cma *cma) { } + static inline void dma_contiguous_reserve(phys_addr_t limit) { } +static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, + phys_addr_t limit, struct cma **res_cma) { + return -ENOSYS; +} + static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size, phys_addr_t base, phys_addr_t limit) diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 94af41858513..3a8d0a2af607 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -132,9 +132,8 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask) static inline void *dma_zalloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { - void *ret = dma_alloc_coherent(dev, size, dma_handle, flag); - if (ret) - memset(ret, 0, size); + void *ret = dma_alloc_coherent(dev, size, dma_handle, + flag | __GFP_ZERO); return ret; } diff --git a/include/linux/dma/mmp-pdma.h b/include/linux/dma/mmp-pdma.h new file mode 100644 index 000000000000..2dc9b2bc18fc --- /dev/null +++ b/include/linux/dma/mmp-pdma.h @@ -0,0 +1,15 @@ +#ifndef _MMP_PDMA_H_ +#define _MMP_PDMA_H_ + +struct dma_chan; + +#ifdef CONFIG_MMP_PDMA +bool mmp_pdma_filter_fn(struct dma_chan *chan, void *param); +#else +static inline bool mmp_pdma_filter_fn(struct dma_chan *chan, void *param) +{ + return false; +} +#endif + +#endif /* _MMP_PDMA_H_ */ diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 91ac8da25020..0bc727534108 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -38,7 +38,10 @@ typedef s32 dma_cookie_t; #define DMA_MIN_COOKIE 1 #define DMA_MAX_COOKIE INT_MAX -#define dma_submit_error(cookie) ((cookie) < 0 ? 1 : 0) +static inline int dma_submit_error(dma_cookie_t cookie) +{ + return cookie < 0 ? cookie : 0; +} /** * enum dma_status - DMA transaction status @@ -66,7 +69,6 @@ enum dma_transaction_type { DMA_PQ, DMA_XOR_VAL, DMA_PQ_VAL, - DMA_MEMSET, DMA_INTERRUPT, DMA_SG, DMA_PRIVATE, @@ -371,6 +373,25 @@ struct dma_slave_config { unsigned int slave_id; }; +/* struct dma_slave_caps - expose capabilities of a slave channel only + * + * @src_addr_widths: bit mask of src addr widths the channel supports + * @dstn_addr_widths: bit mask of dstn addr widths the channel supports + * @directions: bit mask of slave direction the channel supported + * since the enum dma_transfer_direction is not defined as bits for each + * type of direction, the dma controller should fill (1 << <TYPE>) and same + * should be checked by controller as well + * @cmd_pause: true, if pause and thereby resume is supported + * @cmd_terminate: true, if terminate cmd is supported + */ +struct dma_slave_caps { + u32 src_addr_widths; + u32 dstn_addr_widths; + u32 directions; + bool cmd_pause; + bool cmd_terminate; +}; + static inline const char *dma_chan_name(struct dma_chan *chan) { return dev_name(&chan->dev->device); @@ -520,7 +541,6 @@ struct dma_tx_state { * @device_prep_dma_xor_val: prepares a xor validation operation * @device_prep_dma_pq: prepares a pq operation * @device_prep_dma_pq_val: prepares a pqzero_sum operation - * @device_prep_dma_memset: prepares a memset operation * @device_prep_dma_interrupt: prepares an end of chain interrupt operation * @device_prep_slave_sg: prepares a slave dma operation * @device_prep_dma_cyclic: prepare a cyclic dma operation suitable for audio. @@ -534,6 +554,7 @@ struct dma_tx_state { * struct with auxiliary transfer status information, otherwise the call * will just return a simple status code * @device_issue_pending: push pending transactions to hardware + * @device_slave_caps: return the slave channel capabilities */ struct dma_device { @@ -573,9 +594,6 @@ struct dma_device { struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src, unsigned int src_cnt, const unsigned char *scf, size_t len, enum sum_check_flags *pqres, unsigned long flags); - struct dma_async_tx_descriptor *(*device_prep_dma_memset)( - struct dma_chan *chan, dma_addr_t dest, int value, size_t len, - unsigned long flags); struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)( struct dma_chan *chan, unsigned long flags); struct dma_async_tx_descriptor *(*device_prep_dma_sg)( @@ -602,6 +620,7 @@ struct dma_device { dma_cookie_t cookie, struct dma_tx_state *txstate); void (*device_issue_pending)(struct dma_chan *chan); + int (*device_slave_caps)(struct dma_chan *chan, struct dma_slave_caps *caps); }; static inline int dmaengine_device_control(struct dma_chan *chan, @@ -675,6 +694,21 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma( return chan->device->device_prep_interleaved_dma(chan, xt, flags); } +static inline int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps) +{ + if (!chan || !caps) + return -EINVAL; + + /* check if the channel supports slave transactions */ + if (!test_bit(DMA_SLAVE, chan->device->cap_mask.bits)) + return -ENXIO; + + if (chan->device->device_slave_caps) + return chan->device->device_slave_caps(chan, caps); + + return -ENXIO; +} + static inline int dmaengine_terminate_all(struct dma_chan *chan) { return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0); @@ -963,14 +997,24 @@ dma_set_tx_state(struct dma_tx_state *st, dma_cookie_t last, dma_cookie_t used, } } -enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); #ifdef CONFIG_DMA_ENGINE +struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); +enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); void dma_issue_pending_all(void); -struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param); -struct dma_chan *dma_request_slave_channel(struct device *dev, char *name); +struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, + dma_filter_fn fn, void *fn_param); +struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name); void dma_release_channel(struct dma_chan *chan); #else +static inline struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type) +{ + return NULL; +} +static inline enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie) +{ + return DMA_SUCCESS; +} static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) { return DMA_SUCCESS; @@ -978,13 +1022,13 @@ static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descript static inline void dma_issue_pending_all(void) { } -static inline struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, +static inline struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param) { return NULL; } static inline struct dma_chan *dma_request_slave_channel(struct device *dev, - char *name) + const char *name) { return NULL; } @@ -998,16 +1042,16 @@ static inline void dma_release_channel(struct dma_chan *chan) int dma_async_device_register(struct dma_device *device); void dma_async_device_unregister(struct dma_device *device); void dma_run_dependencies(struct dma_async_tx_descriptor *tx); -struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); +struct dma_chan *dma_get_slave_channel(struct dma_chan *chan); struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) #define dma_request_slave_channel_compat(mask, x, y, dev, name) \ __dma_request_slave_channel_compat(&(mask), x, y, dev, name) static inline struct dma_chan -*__dma_request_slave_channel_compat(dma_cap_mask_t *mask, dma_filter_fn fn, - void *fn_param, struct device *dev, - char *name) +*__dma_request_slave_channel_compat(const dma_cap_mask_t *mask, + dma_filter_fn fn, void *fn_param, + struct device *dev, char *name) { struct dma_chan *chan; diff --git a/include/linux/dmi.h b/include/linux/dmi.h index f156cca25ad0..b6eb7a05d58e 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -99,6 +99,7 @@ extern const char * dmi_get_system_info(int field); extern const struct dmi_device * dmi_find_device(int type, const char *name, const struct dmi_device *from); extern void dmi_scan_machine(void); +extern void dmi_set_dump_stack_arch_desc(void); extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp); extern int dmi_name_in_vendors(const char *str); extern int dmi_name_in_serial(const char *str); @@ -114,6 +115,7 @@ static inline const char * dmi_get_system_info(int field) { return NULL; } static inline const struct dmi_device * dmi_find_device(int type, const char *name, const struct dmi_device *from) { return NULL; } static inline void dmi_scan_machine(void) { return; } +static inline void dmi_set_dump_stack_arch_desc(void) { } static inline bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp) { if (yearp) diff --git a/include/linux/drbd.h b/include/linux/drbd.h index 0c5a18ec322c..de7d74ab3de6 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h @@ -52,7 +52,7 @@ #endif extern const char *drbd_buildtag(void); -#define REL_VERSION "8.4.2" +#define REL_VERSION "8.4.3" #define API_VERSION 1 #define PRO_VERSION_MIN 86 #define PRO_VERSION_MAX 101 @@ -177,7 +177,11 @@ enum drbd_ret_code { ERR_NEED_APV_100 = 163, ERR_NEED_ALLOW_TWO_PRI = 164, ERR_MD_UNCLEAN = 165, - + ERR_MD_LAYOUT_CONNECTED = 166, + ERR_MD_LAYOUT_TOO_BIG = 167, + ERR_MD_LAYOUT_TOO_SMALL = 168, + ERR_MD_LAYOUT_NO_FIT = 169, + ERR_IMPLICIT_SHRINK = 170, /* insert new ones above this line */ AFTER_LAST_ERR_CODE }; @@ -319,7 +323,8 @@ enum drbd_state_rv { SS_IN_TRANSIENT_STATE = -18, /* Retry after the next state change */ SS_CONCURRENT_ST_CHG = -19, /* Concurrent cluster side state change! */ SS_O_VOL_PEER_PRI = -20, - SS_AFTER_LAST_ERROR = -21, /* Keep this at bottom */ + SS_OUTDATE_WO_CONN = -21, + SS_AFTER_LAST_ERROR = -22, /* Keep this at bottom */ }; /* from drbd_strings.c */ diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h index d0d8fac8a6e4..e8c44572b8cb 100644 --- a/include/linux/drbd_genl.h +++ b/include/linux/drbd_genl.h @@ -181,6 +181,8 @@ GENL_struct(DRBD_NLA_RESIZE_PARMS, 7, resize_parms, __u64_field(1, DRBD_GENLA_F_MANDATORY, resize_size) __flg_field(2, DRBD_GENLA_F_MANDATORY, resize_force) __flg_field(3, DRBD_GENLA_F_MANDATORY, no_resync) + __u32_field_def(4, 0 /* OPTIONAL */, al_stripes, DRBD_AL_STRIPES_DEF) + __u32_field_def(5, 0 /* OPTIONAL */, al_stripe_size, DRBD_AL_STRIPE_SIZE_DEF) ) GENL_struct(DRBD_NLA_STATE_INFO, 8, state_info, diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h index 1fa19c5f5e64..17e50bb00521 100644 --- a/include/linux/drbd_limits.h +++ b/include/linux/drbd_limits.h @@ -126,13 +126,12 @@ #define DRBD_RESYNC_RATE_DEF 250 #define DRBD_RESYNC_RATE_SCALE 'k' /* kilobytes */ - /* less than 7 would hit performance unnecessarily. - * 919 slots context information per transaction, - * 32k activity log, 4k transaction size, - * one transaction in flight: - * 919 * 7 = 6433 */ + /* less than 7 would hit performance unnecessarily. */ #define DRBD_AL_EXTENTS_MIN 7 -#define DRBD_AL_EXTENTS_MAX 6433 + /* we use u16 as "slot number", (u16)~0 is "FREE". + * If you use >= 292 kB on-disk ring buffer, + * this is the maximum you can use: */ +#define DRBD_AL_EXTENTS_MAX 0xfffe #define DRBD_AL_EXTENTS_DEF 1237 #define DRBD_AL_EXTENTS_SCALE '1' @@ -216,4 +215,13 @@ #define DRBD_ALWAYS_ASBP_DEF 0 #define DRBD_USE_RLE_DEF 1 +#define DRBD_AL_STRIPES_MIN 1 +#define DRBD_AL_STRIPES_MAX 1024 +#define DRBD_AL_STRIPES_DEF 1 +#define DRBD_AL_STRIPES_SCALE '1' + +#define DRBD_AL_STRIPE_SIZE_MIN 4 +#define DRBD_AL_STRIPE_SIZE_MAX 16777216 +#define DRBD_AL_STRIPE_SIZE_DEF 32 +#define DRBD_AL_STRIPE_SIZE_SCALE 'k' /* kilobytes */ #endif diff --git a/include/linux/dw_apb_timer.h b/include/linux/dw_apb_timer.h index dd755ce2a5eb..1f79b20918b1 100644 --- a/include/linux/dw_apb_timer.h +++ b/include/linux/dw_apb_timer.h @@ -51,7 +51,5 @@ dw_apb_clocksource_init(unsigned rating, const char *name, void __iomem *base, void dw_apb_clocksource_register(struct dw_apb_clocksource *dw_cs); void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs); cycle_t dw_apb_clocksource_read(struct dw_apb_clocksource *dw_cs); -void dw_apb_clocksource_unregister(struct dw_apb_clocksource *dw_cs); -extern void dw_apb_timer_init(void); #endif /* __DW_APB_TIMER_H__ */ diff --git a/include/linux/ecryptfs.h b/include/linux/ecryptfs.h index 2224a8c0cb64..8d5ab998a222 100644 --- a/include/linux/ecryptfs.h +++ b/include/linux/ecryptfs.h @@ -6,9 +6,8 @@ #define ECRYPTFS_VERSION_MINOR 0x04 #define ECRYPTFS_SUPPORTED_FILE_VERSION 0x03 /* These flags indicate which features are supported by the kernel - * module; userspace tools such as the mount helper read - * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine - * how to behave. */ + * module; userspace tools such as the mount helper read the feature + * bits from a sysfs handle in order to determine how to behave. */ #define ECRYPTFS_VERSIONING_PASSPHRASE 0x00000001 #define ECRYPTFS_VERSIONING_PUBKEY 0x00000002 #define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004 @@ -19,13 +18,6 @@ #define ECRYPTFS_VERSIONING_HMAC 0x00000080 #define ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION 0x00000100 #define ECRYPTFS_VERSIONING_GCM 0x00000200 -#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ - | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ - | ECRYPTFS_VERSIONING_PUBKEY \ - | ECRYPTFS_VERSIONING_XATTR \ - | ECRYPTFS_VERSIONING_MULTKEY \ - | ECRYPTFS_VERSIONING_DEVMISC \ - | ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION) #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH #define ECRYPTFS_SALT_SIZE 8 diff --git a/include/linux/edac.h b/include/linux/edac.h index 4fd4999ccb5b..5c6d7fbaf89e 100644 --- a/include/linux/edac.h +++ b/include/linux/edac.h @@ -561,7 +561,6 @@ struct csrow_info { u32 ue_count; /* Uncorrectable Errors for this csrow */ u32 ce_count; /* Correctable Errors for this csrow */ - u32 nr_pages; /* combined pages count of all channels */ struct mem_ctl_info *mci; /* the parent */ @@ -623,7 +622,7 @@ struct edac_raw_error_desc { */ struct mem_ctl_info { struct device dev; - struct bus_type bus; + struct bus_type *bus; struct list_head link; /* for global list of mem_ctl_info structs */ @@ -676,11 +675,11 @@ struct mem_ctl_info { * sees memory sticks ("dimms"), and the ones that sees memory ranks. * All old memory controllers enumerate memories per rank, but most * of the recent drivers enumerate memories per DIMM, instead. - * When the memory controller is per rank, mem_is_per_rank is true. + * When the memory controller is per rank, csbased is true. */ unsigned n_layers; struct edac_mc_layer *layers; - bool mem_is_per_rank; + bool csbased; /* * DIMM info. Will eventually remove the entire csrows_info some day @@ -741,8 +740,11 @@ struct mem_ctl_info { u32 fake_inject_ue; u16 fake_inject_count; #endif - __u8 csbased : 1, /* csrow-based memory controller */ - __resv : 7; }; +/* + * Maximum number of memory controllers in the coherent fabric. + */ +#define EDAC_MAX_MCS 16 + #endif diff --git a/include/linux/efi.h b/include/linux/efi.h index 9bf2f1fcae27..5f8f176154f7 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -287,20 +287,20 @@ typedef struct { typedef struct { efi_table_hdr_t hdr; - unsigned long get_time; - unsigned long set_time; - unsigned long get_wakeup_time; - unsigned long set_wakeup_time; - unsigned long set_virtual_address_map; - unsigned long convert_pointer; - unsigned long get_variable; - unsigned long get_next_variable; - unsigned long set_variable; - unsigned long get_next_high_mono_count; - unsigned long reset_system; - unsigned long update_capsule; - unsigned long query_capsule_caps; - unsigned long query_variable_info; + void *get_time; + void *set_time; + void *get_wakeup_time; + void *set_wakeup_time; + void *set_virtual_address_map; + void *convert_pointer; + void *get_variable; + void *get_next_variable; + void *set_variable; + void *get_next_high_mono_count; + void *reset_system; + void *update_capsule; + void *query_capsule_caps; + void *query_variable_info; } efi_runtime_services_t; typedef efi_status_t efi_get_time_t (efi_time_t *tm, efi_time_cap_t *tc); @@ -333,6 +333,7 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules, unsigned long count, u64 *max_size, int *reset_type); +typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long size); /* * EFI Configuration Table and GUID definitions @@ -575,9 +576,15 @@ extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if pos #ifdef CONFIG_X86 extern void efi_late_init(void); extern void efi_free_boot_services(void); +extern efi_status_t efi_query_variable_store(u32 attributes, unsigned long size); #else static inline void efi_late_init(void) {} static inline void efi_free_boot_services(void) {} + +static inline efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) +{ + return EFI_SUCCESS; +} #endif extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); extern u64 efi_get_iobase (void); @@ -587,8 +594,8 @@ extern u64 efi_mem_attribute (unsigned long phys_addr, unsigned long size); extern int __init efi_uart_console_only (void); extern void efi_initialize_iomem_resources(struct resource *code_resource, struct resource *data_resource, struct resource *bss_resource); -extern unsigned long efi_get_time(void); -extern int efi_set_rtc_mmss(unsigned long nowtime); +extern void efi_get_time(struct timespec *now); +extern int efi_set_rtc_mmss(const struct timespec *now); extern void efi_reserve_boot_services(void); extern struct efi_memory_map memmap; @@ -663,6 +670,12 @@ static inline int efi_enabled(int facility) EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \ EFI_VARIABLE_APPEND_WRITE) /* + * Length of a GUID string (strlen("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee")) + * not including trailing NUL + */ +#define EFI_VARIABLE_GUID_LEN 36 + +/* * The type of search to perform when calling boottime->locate_handle */ #define EFI_LOCATE_ALL_HANDLES 0 @@ -719,7 +732,6 @@ static inline void memrange_efi_to_native(u64 *addr, u64 *npages) *addr &= PAGE_MASK; } -#if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE) /* * EFI Variable support. * @@ -731,7 +743,7 @@ struct efivar_operations { efi_get_variable_t *get_variable; efi_get_next_variable_t *get_next_variable; efi_set_variable_t *set_variable; - efi_query_variable_info_t *query_variable_info; + efi_query_variable_store_t *query_variable_store; }; struct efivars { @@ -745,19 +757,88 @@ struct efivars { * which is protected by the BKL, so that path is safe. */ spinlock_t lock; - struct list_head list; struct kset *kset; struct kobject *kobject; - struct bin_attribute *new_var, *del_var; const struct efivar_operations *ops; - struct efivar_entry *walk_entry; - struct pstore_info efi_pstore_info; }; -int register_efivars(struct efivars *efivars, +/* + * The maximum size of VariableName + Data = 1024 + * Therefore, it's reasonable to save that much + * space in each part of the structure, + * and we use a page for reading/writing. + */ + +struct efi_variable { + efi_char16_t VariableName[1024/sizeof(efi_char16_t)]; + efi_guid_t VendorGuid; + unsigned long DataSize; + __u8 Data[1024]; + efi_status_t Status; + __u32 Attributes; +} __attribute__((packed)); + +struct efivar_entry { + struct efi_variable var; + struct list_head list; + struct kobject kobj; +}; + +extern struct list_head efivar_sysfs_list; + +static inline void +efivar_unregister(struct efivar_entry *var) +{ + kobject_put(&var->kobj); +} + +int efivars_register(struct efivars *efivars, const struct efivar_operations *ops, - struct kobject *parent_kobj); -void unregister_efivars(struct efivars *efivars); + struct kobject *kobject); +int efivars_unregister(struct efivars *efivars); +struct kobject *efivars_kobject(void); + +int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), + void *data, bool atomic, bool duplicates, + struct list_head *head); + +void efivar_entry_add(struct efivar_entry *entry, struct list_head *head); +void efivar_entry_remove(struct efivar_entry *entry); + +int __efivar_entry_delete(struct efivar_entry *entry); +int efivar_entry_delete(struct efivar_entry *entry); + +int efivar_entry_size(struct efivar_entry *entry, unsigned long *size); +int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes, + unsigned long *size, void *data); +int efivar_entry_get(struct efivar_entry *entry, u32 *attributes, + unsigned long *size, void *data); +int efivar_entry_set(struct efivar_entry *entry, u32 attributes, + unsigned long size, void *data, struct list_head *head); +int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes, + unsigned long *size, void *data, bool *set); +int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes, + bool block, unsigned long size, void *data); + +void efivar_entry_iter_begin(void); +void efivar_entry_iter_end(void); + +int __efivar_entry_iter(int (*func)(struct efivar_entry *, void *), + struct list_head *head, void *data, + struct efivar_entry **prev); +int efivar_entry_iter(int (*func)(struct efivar_entry *, void *), + struct list_head *head, void *data); + +struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid, + struct list_head *head, bool remove); + +bool efivar_validate(struct efi_variable *var, u8 *data, unsigned long len); + +extern struct work_struct efivar_work; +void efivar_run_worker(void); + +#if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE) +int efivars_sysfs_init(void); #endif /* CONFIG_EFI_VARS */ diff --git a/include/linux/elevator.h b/include/linux/elevator.h index acd0312d46fb..306dd8cd0b6f 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -7,6 +7,7 @@ #ifdef CONFIG_BLOCK struct io_cq; +struct elevator_type; typedef int (elevator_merge_fn) (struct request_queue *, struct request **, struct bio *); @@ -35,7 +36,8 @@ typedef void (elevator_put_req_fn) (struct request *); typedef void (elevator_activate_req_fn) (struct request_queue *, struct request *); typedef void (elevator_deactivate_req_fn) (struct request_queue *, struct request *); -typedef int (elevator_init_fn) (struct request_queue *); +typedef int (elevator_init_fn) (struct request_queue *, + struct elevator_type *e); typedef void (elevator_exit_fn) (struct elevator_queue *); struct elevator_ops @@ -155,6 +157,8 @@ extern int elevator_init(struct request_queue *, char *); extern void elevator_exit(struct elevator_queue *); extern int elevator_change(struct request_queue *, const char *); extern bool elv_rq_merge_ok(struct request *, struct bio *); +extern struct elevator_queue *elevator_alloc(struct request_queue *, + struct elevator_type *); /* * Helper functions. diff --git a/include/linux/err.h b/include/linux/err.h index f2edce25a76b..15f92e072450 100644 --- a/include/linux/err.h +++ b/include/linux/err.h @@ -24,17 +24,17 @@ static inline void * __must_check ERR_PTR(long error) return (void *) error; } -static inline long __must_check PTR_ERR(const void *ptr) +static inline long __must_check PTR_ERR(__force const void *ptr) { return (long) ptr; } -static inline long __must_check IS_ERR(const void *ptr) +static inline long __must_check IS_ERR(__force const void *ptr) { return IS_ERR_VALUE((unsigned long)ptr); } -static inline long __must_check IS_ERR_OR_NULL(const void *ptr) +static inline long __must_check IS_ERR_OR_NULL(__force const void *ptr) { return !ptr || IS_ERR_VALUE((unsigned long)ptr); } @@ -46,13 +46,13 @@ static inline long __must_check IS_ERR_OR_NULL(const void *ptr) * Explicitly cast an error-valued pointer to another pointer type in such a * way as to make it clear that's what's going on. */ -static inline void * __must_check ERR_CAST(const void *ptr) +static inline void * __must_check ERR_CAST(__force const void *ptr) { /* cast away the const */ return (void *) ptr; } -static inline int __must_check PTR_RET(const void *ptr) +static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr) { if (IS_ERR(ptr)) return PTR_ERR(ptr); @@ -60,6 +60,9 @@ static inline int __must_check PTR_RET(const void *ptr) return 0; } +/* Deprecated */ +#define PTR_RET(p) PTR_ERR_OR_ZERO(p) + #endif #endif /* _LINUX_ERR_H */ diff --git a/include/linux/errno.h b/include/linux/errno.h index f6bf082d4d4f..89627b9187f9 100644 --- a/include/linux/errno.h +++ b/include/linux/errno.h @@ -28,6 +28,5 @@ #define EBADTYPE 527 /* Type not supported by server */ #define EJUKEBOX 528 /* Request initiated, but will not complete before timeout */ #define EIOCBQUEUED 529 /* iocb queued, will get completion event */ -#define EIOCBRETRY 530 /* iocb queued, will trigger a retry */ #endif diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index c623861964e4..d8b512496e50 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -199,6 +199,21 @@ static inline void eth_hw_addr_random(struct net_device *dev) } /** + * eth_hw_addr_inherit - Copy dev_addr from another net_device + * @dst: pointer to net_device to copy dev_addr to + * @src: pointer to net_device to copy dev_addr from + * + * Copy the Ethernet address from one net_device to another along with + * the address attributes (addr_assign_type). + */ +static inline void eth_hw_addr_inherit(struct net_device *dst, + struct net_device *src) +{ + dst->addr_assign_type = src->addr_assign_type; + memcpy(dst->dev_addr, src->dev_addr, ETH_ALEN); +} + +/** * compare_ether_addr - Compare two Ethernet addresses * @addr1: Pointer to a six-byte array containing the Ethernet address * @addr2: Pointer other six-byte array containing the Ethernet address diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h index cf5d2af61b81..ff0b981f078e 100644 --- a/include/linux/eventfd.h +++ b/include/linux/eventfd.h @@ -9,7 +9,6 @@ #define _LINUX_EVENTFD_H #include <linux/fcntl.h> -#include <linux/file.h> #include <linux/wait.h> /* @@ -26,6 +25,8 @@ #define EFD_SHARED_FCNTL_FLAGS (O_CLOEXEC | O_NONBLOCK) #define EFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS | EFD_SEMAPHORE) +struct file; + #ifdef CONFIG_EVENTFD struct file *eventfd_file_create(unsigned int count, int flags); diff --git a/include/linux/evm.h b/include/linux/evm.h index 9fc13a760928..1fcb88ca88de 100644 --- a/include/linux/evm.h +++ b/include/linux/evm.h @@ -96,5 +96,5 @@ static inline int evm_inode_init_security(struct inode *inode, return 0; } -#endif /* CONFIG_EVM_H */ +#endif /* CONFIG_EVM */ #endif /* LINUX_EVM_H */ diff --git a/include/linux/export.h b/include/linux/export.h index 696c0f48afc7..412cd509effe 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -5,17 +5,24 @@ * to reduce the amount of pointless cruft we feed to gcc when only * exporting a simple symbol or two. * - * If you feel the need to add #include <linux/foo.h> to this file - * then you are doing something wrong and should go away silently. + * Try not to add #includes here. It slows compilation and makes kernel + * hackers place grumpy comments in header files. */ /* Some toolchains use a `_' prefix for all user symbols. */ -#ifdef CONFIG_SYMBOL_PREFIX -#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX +#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX +#define __VMLINUX_SYMBOL(x) _##x +#define __VMLINUX_SYMBOL_STR(x) "_" #x #else -#define MODULE_SYMBOL_PREFIX "" +#define __VMLINUX_SYMBOL(x) x +#define __VMLINUX_SYMBOL_STR(x) #x #endif +/* Indirect, so macros are expanded before pasting. */ +#define VMLINUX_SYMBOL(x) __VMLINUX_SYMBOL(x) +#define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x) + +#ifndef __ASSEMBLY__ struct kernel_symbol { unsigned long value; @@ -51,7 +58,7 @@ extern struct module __this_module; __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ __attribute__((section("__ksymtab_strings"), aligned(1))) \ - = MODULE_SYMBOL_PREFIX #sym; \ + = VMLINUX_SYMBOL_STR(sym); \ static const struct kernel_symbol __ksymtab_##sym \ __used \ __attribute__((section("___ksymtab" sec "+" #sym), unused)) \ @@ -85,5 +92,6 @@ extern struct module __this_module; #define EXPORT_UNUSED_SYMBOL_GPL(sym) #endif /* CONFIG_MODULES */ +#endif /* !__ASSEMBLY__ */ #endif /* _LINUX_EXPORT_H */ diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index 5b9b5b317180..41b223a59a63 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -85,6 +85,17 @@ enum fid_type { FILEID_NILFS_WITH_PARENT = 0x62, /* + * 32 bit generation number, 40 bit i_pos. + */ + FILEID_FAT_WITHOUT_PARENT = 0x71, + + /* + * 32 bit generation number, 40 bit i_pos, + * 32 bit parent generation number, 40 bit parent i_pos + */ + FILEID_FAT_WITH_PARENT = 0x72, + + /* * Filesystems must not use 0xff file ID. */ FILEID_INVALID = 0xff, diff --git a/include/linux/extcon/of_extcon.h b/include/linux/extcon/of_extcon.h new file mode 100644 index 000000000000..0ebfeff1b55d --- /dev/null +++ b/include/linux/extcon/of_extcon.h @@ -0,0 +1,31 @@ +/* + * OF helpers for External connector (extcon) framework + * + * Copyright (C) 2013 Texas Instruments, Inc. + * Kishon Vijay Abraham I <kishon@ti.com> + * + * Copyright (C) 2013 Samsung Electronics + * Chanwoo Choi <cw00.choi@samsung.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_EXTCON_H +#define __LINUX_OF_EXTCON_H + +#include <linux/err.h> + +#if IS_ENABLED(CONFIG_OF_EXTCON) +extern struct extcon_dev + *of_extcon_get_extcon_dev(struct device *dev, int index); +#else +static inline struct extcon_dev + *of_extcon_get_extcon_dev(struct device *dev, int index) +{ + return ERR_PTR(-ENOSYS); +} +#endif /* CONFIG_OF_EXTCON */ +#endif /* __LINUX_OF_EXTCON_H */ diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index f9a12f6243a5..bb942f6d5702 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -20,8 +20,8 @@ #define F2FS_BLKSIZE 4096 /* support only 4KB block */ #define F2FS_MAX_EXTENSION 64 /* # of extension entries */ -#define NULL_ADDR 0x0U -#define NEW_ADDR -1U +#define NULL_ADDR ((block_t)0) /* used as block_t addresses */ +#define NEW_ADDR ((block_t)-1) /* used as block_t addresses */ #define F2FS_ROOT_INO(sbi) (sbi->root_ino_num) #define F2FS_NODE_INO(sbi) (sbi->node_ino_num) @@ -139,15 +139,25 @@ struct f2fs_extent { __le32 len; /* lengh of the extent */ } __packed; -#define F2FS_MAX_NAME_LEN 256 -#define ADDRS_PER_INODE 923 /* Address Pointers in an Inode */ -#define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ -#define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */ +#define F2FS_NAME_LEN 255 +#define F2FS_INLINE_XATTR_ADDRS 50 /* 200 bytes for inline xattrs */ +#define DEF_ADDRS_PER_INODE 923 /* Address Pointers in an Inode */ +#define ADDRS_PER_INODE(fi) addrs_per_inode(fi) +#define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ +#define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */ + +#define NODE_DIR1_BLOCK (DEF_ADDRS_PER_INODE + 1) +#define NODE_DIR2_BLOCK (DEF_ADDRS_PER_INODE + 2) +#define NODE_IND1_BLOCK (DEF_ADDRS_PER_INODE + 3) +#define NODE_IND2_BLOCK (DEF_ADDRS_PER_INODE + 4) +#define NODE_DIND_BLOCK (DEF_ADDRS_PER_INODE + 5) + +#define F2FS_INLINE_XATTR 0x01 /* file inline xattr flag */ struct f2fs_inode { __le16 i_mode; /* file mode */ __u8 i_advise; /* file hints */ - __u8 i_reserved; /* reserved */ + __u8 i_inline; /* file inline flags */ __le32 i_uid; /* user ID */ __le32 i_gid; /* group ID */ __le32 i_links; /* links count */ @@ -165,11 +175,12 @@ struct f2fs_inode { __le32 i_flags; /* file attributes */ __le32 i_pino; /* parent inode number */ __le32 i_namelen; /* file name length */ - __u8 i_name[F2FS_MAX_NAME_LEN]; /* file name for SPOR */ + __u8 i_name[F2FS_NAME_LEN]; /* file name for SPOR */ + __u8 i_reserved2; /* for backward compatibility */ struct f2fs_extent i_ext; /* caching a largest extent */ - __le32 i_addr[ADDRS_PER_INODE]; /* Pointers to data blocks */ + __le32 i_addr[DEF_ADDRS_PER_INODE]; /* Pointers to data blocks */ __le32 i_nid[5]; /* direct(2), indirect(2), double_indirect(1) node id */ @@ -362,10 +373,10 @@ struct f2fs_summary_block { typedef __le32 f2fs_hash_t; /* One directory entry slot covers 8bytes-long file name */ -#define F2FS_NAME_LEN 8 -#define F2FS_NAME_LEN_BITS 3 +#define F2FS_SLOT_LEN 8 +#define F2FS_SLOT_LEN_BITS 3 -#define GET_DENTRY_SLOTS(x) ((x + F2FS_NAME_LEN - 1) >> F2FS_NAME_LEN_BITS) +#define GET_DENTRY_SLOTS(x) ((x + F2FS_SLOT_LEN - 1) >> F2FS_SLOT_LEN_BITS) /* the number of dentry in a block */ #define NR_DENTRY_IN_BLOCK 214 @@ -377,10 +388,10 @@ typedef __le32 f2fs_hash_t; #define SIZE_OF_DENTRY_BITMAP ((NR_DENTRY_IN_BLOCK + BITS_PER_BYTE - 1) / \ BITS_PER_BYTE) #define SIZE_OF_RESERVED (PAGE_SIZE - ((SIZE_OF_DIR_ENTRY + \ - F2FS_NAME_LEN) * \ + F2FS_SLOT_LEN) * \ NR_DENTRY_IN_BLOCK + SIZE_OF_DENTRY_BITMAP)) -/* One directory entry slot representing F2FS_NAME_LEN-sized file name */ +/* One directory entry slot representing F2FS_SLOT_LEN-sized file name */ struct f2fs_dir_entry { __le32 hash_code; /* hash code of file name */ __le32 ino; /* inode number */ @@ -394,7 +405,7 @@ struct f2fs_dentry_block { __u8 dentry_bitmap[SIZE_OF_DENTRY_BITMAP]; __u8 reserved[SIZE_OF_RESERVED]; struct f2fs_dir_entry dentry[NR_DENTRY_IN_BLOCK]; - __u8 filename[NR_DENTRY_IN_BLOCK][F2FS_NAME_LEN]; + __u8 filename[NR_DENTRY_IN_BLOCK][F2FS_SLOT_LEN]; } __packed; /* file types used in inode_info->flags */ diff --git a/include/linux/fb.h b/include/linux/fb.h index 58b98606ac26..ffac70aab3e9 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -501,6 +501,8 @@ struct fb_info { resource_size_t size; } ranges[0]; } *apertures; + + bool skip_vt_switch; /* no VT switch on suspend/resume required */ }; static inline struct apertures_struct *alloc_apertures(unsigned int max_num) { @@ -622,7 +624,7 @@ extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u3 extern void fb_set_suspend(struct fb_info *info, int state); extern int fb_get_color_depth(struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix); -extern int fb_get_options(char *name, char **option); +extern int fb_get_options(const char *name, char **option); extern int fb_new_modelist(struct fb_info *info); extern struct fb_info *registered_fb[FB_MAX]; diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index fb7dacae0522..085197bd8812 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -27,7 +27,6 @@ struct fdtable { unsigned long *close_on_exec; unsigned long *open_fds; struct rcu_head rcu; - struct fdtable *next; }; static inline bool close_on_exec(int fd, const struct fdtable *fdt) diff --git a/include/linux/filter.h b/include/linux/filter.h index c45eabc135e1..a6ac84871d6d 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -46,10 +46,25 @@ extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); extern int sk_detach_filter(struct sock *sk); extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen); extern int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, unsigned len); +extern void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to); #ifdef CONFIG_BPF_JIT +#include <stdarg.h> +#include <linux/linkage.h> +#include <linux/printk.h> + extern void bpf_jit_compile(struct sk_filter *fp); extern void bpf_jit_free(struct sk_filter *fp); + +static inline void bpf_jit_dump(unsigned int flen, unsigned int proglen, + u32 pass, void *image) +{ + pr_err("flen=%u proglen=%u pass=%u image=%pK\n", + flen, proglen, pass, image); + if (image) + print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_OFFSET, + 16, 1, image, proglen, false); +} #define SK_RUN_FILTER(FILTER, SKB) (*FILTER->bpf_func)(SKB, FILTER->insns) #else static inline void bpf_jit_compile(struct sk_filter *fp) @@ -126,6 +141,7 @@ enum { BPF_S_ANC_SECCOMP_LD_W, BPF_S_ANC_VLAN_TAG, BPF_S_ANC_VLAN_TAG_PRESENT, + BPF_S_ANC_PAY_OFFSET, }; #endif /* __LINUX_FILTER_H__ */ diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 191501afd7fb..5d7782e42b8f 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -251,8 +251,10 @@ struct ieee1394_device_id; struct fw_driver { struct device_driver driver; + int (*probe)(struct fw_unit *unit, const struct ieee1394_device_id *id); /* Called when the parent device sits through a bus reset. */ void (*update)(struct fw_unit *unit); + void (*remove)(struct fw_unit *unit); const struct ieee1394_device_id *id_table; }; @@ -434,6 +436,7 @@ struct fw_iso_context { int type; int channel; int speed; + bool drop_overflow_headers; size_t header_size; union { fw_iso_callback_t sc; diff --git a/include/linux/firmware.h b/include/linux/firmware.h index e4279fedb93a..e154c1005cd1 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -47,8 +47,6 @@ int request_firmware_nowait( void (*cont)(const struct firmware *fw, void *context)); void release_firmware(const struct firmware *fw); -int cache_firmware(const char *name); -int uncache_firmware(const char *name); #else static inline int request_firmware(const struct firmware **fw, const char *name, @@ -68,15 +66,6 @@ static inline void release_firmware(const struct firmware *fw) { } -static inline int cache_firmware(const char *name) -{ - return -ENOENT; -} - -static inline int uncache_firmware(const char *name) -{ - return -EINVAL; -} #endif #endif diff --git a/include/linux/fmc-sdb.h b/include/linux/fmc-sdb.h new file mode 100644 index 000000000000..1974317a9b3d --- /dev/null +++ b/include/linux/fmc-sdb.h @@ -0,0 +1,36 @@ +/* + * This file is separate from sdb.h, because I want that one to remain + * unchanged (as far as possible) from the official sdb distribution + * + * This file and associated functionality are a playground for me to + * understand stuff which will later be implemented in more generic places. + */ +#include <linux/sdb.h> + +/* This is the union of all currently defined types */ +union sdb_record { + struct sdb_interconnect ic; + struct sdb_device dev; + struct sdb_bridge bridge; + struct sdb_integration integr; + struct sdb_empty empty; +}; + +struct fmc_device; + +/* Every sdb table is turned into this structure */ +struct sdb_array { + int len; + int level; + unsigned long baseaddr; + struct fmc_device *fmc; /* the device that hosts it */ + struct sdb_array *parent; /* NULL at root */ + union sdb_record *record; /* copies of the struct */ + struct sdb_array **subtree; /* only valid for bridge items */ +}; + +extern int fmc_scan_sdb_tree(struct fmc_device *fmc, unsigned long address); +extern void fmc_show_sdb_tree(const struct fmc_device *fmc); +extern signed long fmc_find_sdb_device(struct sdb_array *tree, uint64_t vendor, + uint32_t device, unsigned long *sz); +extern int fmc_free_sdb_tree(struct fmc_device *fmc); diff --git a/include/linux/fmc.h b/include/linux/fmc.h new file mode 100644 index 000000000000..a5f0aa5c2a8d --- /dev/null +++ b/include/linux/fmc.h @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2012 CERN (www.cern.ch) + * Author: Alessandro Rubini <rubini@gnudd.com> + * + * Released according to the GNU GPL, version 2 or any later version. + * + * This work is part of the White Rabbit project, a research effort led + * by CERN, the European Institute for Nuclear Research. + */ +#ifndef __LINUX_FMC_H__ +#define __LINUX_FMC_H__ +#include <linux/types.h> +#include <linux/moduleparam.h> +#include <linux/device.h> +#include <linux/list.h> +#include <linux/interrupt.h> +#include <linux/io.h> + +struct fmc_device; +struct fmc_driver; + +/* + * This bus abstraction is developed separately from drivers, so we need + * to check the version of the data structures we receive. + */ + +#define FMC_MAJOR 3 +#define FMC_MINOR 0 +#define FMC_VERSION ((FMC_MAJOR << 16) | FMC_MINOR) +#define __FMC_MAJOR(x) ((x) >> 16) +#define __FMC_MINOR(x) ((x) & 0xffff) + +/* + * The device identification, as defined by the IPMI FRU (Field Replaceable + * Unit) includes four different strings to describe the device. Here we + * only match the "Board Manufacturer" and the "Board Product Name", + * ignoring the "Board Serial Number" and "Board Part Number". All 4 are + * expected to be strings, so they are treated as zero-terminated C strings. + * Unspecified string (NULL) means "any", so if both are unspecified this + * is a catch-all driver. So null entries are allowed and we use array + * and length. This is unlike pci and usb that use null-terminated arrays + */ +struct fmc_fru_id { + char *manufacturer; + char *product_name; +}; + +/* + * If the FPGA is already programmed (think Etherbone or the second + * SVEC slot), we can match on SDB devices in the memory image. This + * match uses an array of devices that must all be present, and the + * match is based on vendor and device only. Further checks are expected + * to happen in the probe function. Zero means "any" and catch-all is allowed. + */ +struct fmc_sdb_one_id { + uint64_t vendor; + uint32_t device; +}; +struct fmc_sdb_id { + struct fmc_sdb_one_id *cores; + int cores_nr; +}; + +struct fmc_device_id { + struct fmc_fru_id *fru_id; + int fru_id_nr; + struct fmc_sdb_id *sdb_id; + int sdb_id_nr; +}; + +/* This sizes the module_param_array used by generic module parameters */ +#define FMC_MAX_CARDS 32 + +/* The driver is a pretty simple thing */ +struct fmc_driver { + unsigned long version; + struct device_driver driver; + int (*probe)(struct fmc_device *); + int (*remove)(struct fmc_device *); + const struct fmc_device_id id_table; + /* What follows is for generic module parameters */ + int busid_n; + int busid_val[FMC_MAX_CARDS]; + int gw_n; + char *gw_val[FMC_MAX_CARDS]; +}; +#define to_fmc_driver(x) container_of((x), struct fmc_driver, driver) + +/* These are the generic parameters, that drivers may instantiate */ +#define FMC_PARAM_BUSID(_d) \ + module_param_array_named(busid, _d.busid_val, int, &_d.busid_n, 0444) +#define FMC_PARAM_GATEWARE(_d) \ + module_param_array_named(gateware, _d.gw_val, charp, &_d.gw_n, 0444) + +/* + * Drivers may need to configure gpio pins in the carrier. To read input + * (a very uncommon operation, and definitely not in the hot paths), just + * configure one gpio only and get 0 or 1 as retval of the config method + */ +struct fmc_gpio { + char *carrier_name; /* name or NULL for virtual pins */ + int gpio; + int _gpio; /* internal use by the carrier */ + int mode; /* GPIOF_DIR_OUT etc, from <linux/gpio.h> */ + int irqmode; /* IRQF_TRIGGER_LOW and so on */ +}; + +/* The numbering of gpio pins allows access to raw pins or virtual roles */ +#define FMC_GPIO_RAW(x) (x) /* 4096 of them */ +#define __FMC_GPIO_IS_RAW(x) ((x) < 0x1000) +#define FMC_GPIO_IRQ(x) ((x) + 0x1000) /* 256 of them */ +#define FMC_GPIO_LED(x) ((x) + 0x1100) /* 256 of them */ +#define FMC_GPIO_KEY(x) ((x) + 0x1200) /* 256 of them */ +#define FMC_GPIO_TP(x) ((x) + 0x1300) /* 256 of them */ +#define FMC_GPIO_USER(x) ((x) + 0x1400) /* 256 of them */ +/* We may add SCL and SDA, or other roles if the need arises */ + +/* GPIOF_DIR_IN etc are missing before 3.0. copy from <linux/gpio.h> */ +#ifndef GPIOF_DIR_IN +# define GPIOF_DIR_OUT (0 << 0) +# define GPIOF_DIR_IN (1 << 0) +# define GPIOF_INIT_LOW (0 << 1) +# define GPIOF_INIT_HIGH (1 << 1) +#endif + +/* + * The operations are offered by each carrier and should make driver + * design completely independent of the carrier. Named GPIO pins may be + * the exception. + */ +struct fmc_operations { + uint32_t (*read32)(struct fmc_device *fmc, int offset); + void (*write32)(struct fmc_device *fmc, uint32_t value, int offset); + int (*validate)(struct fmc_device *fmc, struct fmc_driver *drv); + int (*reprogram)(struct fmc_device *f, struct fmc_driver *d, char *gw); + int (*irq_request)(struct fmc_device *fmc, irq_handler_t h, + char *name, int flags); + void (*irq_ack)(struct fmc_device *fmc); + int (*irq_free)(struct fmc_device *fmc); + int (*gpio_config)(struct fmc_device *fmc, struct fmc_gpio *gpio, + int ngpio); + int (*read_ee)(struct fmc_device *fmc, int pos, void *d, int l); + int (*write_ee)(struct fmc_device *fmc, int pos, const void *d, int l); +}; + +/* Prefer this helper rather than calling of fmc->reprogram directly */ +extern int fmc_reprogram(struct fmc_device *f, struct fmc_driver *d, char *gw, + int sdb_entry); + +/* + * The device reports all information needed to access hw. + * + * If we have eeprom_len and not contents, the core reads it. + * Then, parsing of identifiers is done by the core which fills fmc_fru_id.. + * Similarly a device that must be matched based on SDB cores must + * fill the entry point and the core will scan the bus (FIXME: sdb match) + */ +struct fmc_device { + unsigned long version; + unsigned long flags; + struct module *owner; /* char device must pin it */ + struct fmc_fru_id id; /* for EEPROM-based match */ + struct fmc_operations *op; /* carrier-provided */ + int irq; /* according to host bus. 0 == none */ + int eeprom_len; /* Usually 8kB, may be less */ + int eeprom_addr; /* 0x50, 0x52 etc */ + uint8_t *eeprom; /* Full contents or leading part */ + char *carrier_name; /* "SPEC" or similar, for special use */ + void *carrier_data; /* "struct spec *" or equivalent */ + __iomem void *fpga_base; /* May be NULL (Etherbone) */ + __iomem void *slot_base; /* Set by the driver */ + struct fmc_device **devarray; /* Allocated by the bus */ + int slot_id; /* Index in the slot array */ + int nr_slots; /* Number of slots in this carrier */ + unsigned long memlen; /* Used for the char device */ + struct device dev; /* For Linux use */ + struct device *hwdev; /* The underlying hardware device */ + unsigned long sdbfs_entry; + struct sdb_array *sdb; + uint32_t device_id; /* Filled by the device */ + char *mezzanine_name; /* Defaults to ``fmc'' */ + void *mezzanine_data; +}; +#define to_fmc_device(x) container_of((x), struct fmc_device, dev) + +#define FMC_DEVICE_HAS_GOLDEN 1 +#define FMC_DEVICE_HAS_CUSTOM 2 +#define FMC_DEVICE_NO_MEZZANINE 4 +#define FMC_DEVICE_MATCH_SDB 8 /* fmc-core must scan sdb in fpga */ + +/* + * If fpga_base can be used, the carrier offers no readl/writel methods, and + * this expands to a single, fast, I/O access. + */ +static inline uint32_t fmc_readl(struct fmc_device *fmc, int offset) +{ + if (unlikely(fmc->op->read32)) + return fmc->op->read32(fmc, offset); + return readl(fmc->fpga_base + offset); +} +static inline void fmc_writel(struct fmc_device *fmc, uint32_t val, int off) +{ + if (unlikely(fmc->op->write32)) + fmc->op->write32(fmc, val, off); + else + writel(val, fmc->fpga_base + off); +} + +/* pci-like naming */ +static inline void *fmc_get_drvdata(const struct fmc_device *fmc) +{ + return dev_get_drvdata(&fmc->dev); +} + +static inline void fmc_set_drvdata(struct fmc_device *fmc, void *data) +{ + dev_set_drvdata(&fmc->dev, data); +} + +/* The 4 access points */ +extern int fmc_driver_register(struct fmc_driver *drv); +extern void fmc_driver_unregister(struct fmc_driver *drv); +extern int fmc_device_register(struct fmc_device *tdev); +extern void fmc_device_unregister(struct fmc_device *tdev); + +/* Two more for device sets, all driven by the same FPGA */ +extern int fmc_device_register_n(struct fmc_device **devs, int n); +extern void fmc_device_unregister_n(struct fmc_device **devs, int n); + +/* Internal cross-calls between files; not exported to other modules */ +extern int fmc_match(struct device *dev, struct device_driver *drv); +extern int fmc_fill_id_info(struct fmc_device *fmc); +extern void fmc_free_id_info(struct fmc_device *fmc); +extern void fmc_dump_eeprom(const struct fmc_device *fmc); +extern void fmc_dump_sdb(const struct fmc_device *fmc); + +#endif /* __LINUX_FMC_H__ */ diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 043a5cf8b5ba..7fd81b8c4897 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -47,16 +47,25 @@ extern int freeze_kernel_threads(void); extern void thaw_processes(void); extern void thaw_kernel_threads(void); -static inline bool try_to_freeze(void) +/* + * DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION + * If try_to_freeze causes a lockdep warning it means the caller may deadlock + */ +static inline bool try_to_freeze_unsafe(void) { - if (!(current->flags & PF_NOFREEZE)) - debug_check_no_locks_held(); might_sleep(); if (likely(!freezing(current))) return false; return __refrigerator(false); } +static inline bool try_to_freeze(void) +{ + if (!(current->flags & PF_NOFREEZE)) + debug_check_no_locks_held(); + return try_to_freeze_unsafe(); +} + extern bool freeze_task(struct task_struct *p); extern bool set_freezable(void); @@ -118,6 +127,14 @@ static inline void freezer_count(void) try_to_freeze(); } +/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */ +static inline void freezer_count_unsafe(void) +{ + current->flags &= ~PF_FREEZER_SKIP; + smp_mb(); + try_to_freeze_unsafe(); +} + /** * freezer_should_skip - whether to skip a task when determining frozen * state is reached @@ -142,28 +159,86 @@ static inline bool freezer_should_skip(struct task_struct *p) } /* - * These macros are intended to be used whenever you want allow a sleeping + * These functions are intended to be used whenever you want allow a sleeping * task to be frozen. Note that neither return any clear indication of * whether a freeze event happened while in this function. */ /* Like schedule(), but should not block the freezer. */ -#define freezable_schedule() \ -({ \ - freezer_do_not_count(); \ - schedule(); \ - freezer_count(); \ -}) +static inline void freezable_schedule(void) +{ + freezer_do_not_count(); + schedule(); + freezer_count(); +} + +/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */ +static inline void freezable_schedule_unsafe(void) +{ + freezer_do_not_count(); + schedule(); + freezer_count_unsafe(); +} + +/* + * Like freezable_schedule_timeout(), but should not block the freezer. Do not + * call this with locks held. + */ +static inline long freezable_schedule_timeout(long timeout) +{ + long __retval; + freezer_do_not_count(); + __retval = schedule_timeout(timeout); + freezer_count(); + return __retval; +} + +/* + * Like schedule_timeout_interruptible(), but should not block the freezer. Do not + * call this with locks held. + */ +static inline long freezable_schedule_timeout_interruptible(long timeout) +{ + long __retval; + freezer_do_not_count(); + __retval = schedule_timeout_interruptible(timeout); + freezer_count(); + return __retval; +} /* Like schedule_timeout_killable(), but should not block the freezer. */ -#define freezable_schedule_timeout_killable(timeout) \ -({ \ - long __retval; \ - freezer_do_not_count(); \ - __retval = schedule_timeout_killable(timeout); \ - freezer_count(); \ - __retval; \ -}) +static inline long freezable_schedule_timeout_killable(long timeout) +{ + long __retval; + freezer_do_not_count(); + __retval = schedule_timeout_killable(timeout); + freezer_count(); + return __retval; +} + +/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */ +static inline long freezable_schedule_timeout_killable_unsafe(long timeout) +{ + long __retval; + freezer_do_not_count(); + __retval = schedule_timeout_killable(timeout); + freezer_count_unsafe(); + return __retval; +} + +/* + * Like schedule_hrtimeout_range(), but should not block the freezer. Do not + * call this with locks held. + */ +static inline int freezable_schedule_hrtimeout_range(ktime_t *expires, + unsigned long delta, const enum hrtimer_mode mode) +{ + int __retval; + freezer_do_not_count(); + __retval = schedule_hrtimeout_range(expires, delta, mode); + freezer_count(); + return __retval; +} /* * Freezer-friendly wrappers around wait_event_interruptible(), @@ -180,33 +255,45 @@ static inline bool freezer_should_skip(struct task_struct *p) __retval; \ }) +/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */ +#define wait_event_freezekillable_unsafe(wq, condition) \ +({ \ + int __retval; \ + freezer_do_not_count(); \ + __retval = wait_event_killable(wq, (condition)); \ + freezer_count_unsafe(); \ + __retval; \ +}) + #define wait_event_freezable(wq, condition) \ ({ \ int __retval; \ - for (;;) { \ - __retval = wait_event_interruptible(wq, \ - (condition) || freezing(current)); \ - if (__retval || (condition)) \ - break; \ - try_to_freeze(); \ - } \ + freezer_do_not_count(); \ + __retval = wait_event_interruptible(wq, (condition)); \ + freezer_count(); \ __retval; \ }) #define wait_event_freezable_timeout(wq, condition, timeout) \ ({ \ long __retval = timeout; \ - for (;;) { \ - __retval = wait_event_interruptible_timeout(wq, \ - (condition) || freezing(current), \ - __retval); \ - if (__retval <= 0 || (condition)) \ - break; \ - try_to_freeze(); \ - } \ + freezer_do_not_count(); \ + __retval = wait_event_interruptible_timeout(wq, (condition), \ + __retval); \ + freezer_count(); \ + __retval; \ +}) + +#define wait_event_freezable_exclusive(wq, condition) \ +({ \ + int __retval; \ + freezer_do_not_count(); \ + __retval = wait_event_interruptible_exclusive(wq, condition); \ + freezer_count(); \ __retval; \ }) + #else /* !CONFIG_FREEZER */ static inline bool frozen(struct task_struct *p) { return false; } static inline bool freezing(struct task_struct *p) { return false; } @@ -228,18 +315,37 @@ static inline void set_freezable(void) {} #define freezable_schedule() schedule() +#define freezable_schedule_unsafe() schedule() + +#define freezable_schedule_timeout(timeout) schedule_timeout(timeout) + +#define freezable_schedule_timeout_interruptible(timeout) \ + schedule_timeout_interruptible(timeout) + #define freezable_schedule_timeout_killable(timeout) \ schedule_timeout_killable(timeout) +#define freezable_schedule_timeout_killable_unsafe(timeout) \ + schedule_timeout_killable(timeout) + +#define freezable_schedule_hrtimeout_range(expires, delta, mode) \ + schedule_hrtimeout_range(expires, delta, mode) + #define wait_event_freezable(wq, condition) \ wait_event_interruptible(wq, condition) #define wait_event_freezable_timeout(wq, condition, timeout) \ wait_event_interruptible_timeout(wq, condition, timeout) +#define wait_event_freezable_exclusive(wq, condition) \ + wait_event_interruptible_exclusive(wq, condition) + #define wait_event_freezekillable(wq, condition) \ wait_event_killable(wq, condition) +#define wait_event_freezekillable_unsafe(wq, condition) \ + wait_event_killable(wq, condition) + #endif /* !CONFIG_FREEZER */ #endif /* FREEZER_H_INCLUDED */ diff --git a/include/linux/frontswap.h b/include/linux/frontswap.h index 30442547b9e6..8293262401de 100644 --- a/include/linux/frontswap.h +++ b/include/linux/frontswap.h @@ -14,7 +14,7 @@ struct frontswap_ops { }; extern bool frontswap_enabled; -extern struct frontswap_ops +extern struct frontswap_ops * frontswap_register_ops(struct frontswap_ops *ops); extern void frontswap_shrink(unsigned long); extern unsigned long frontswap_curr_pages(void); @@ -22,33 +22,19 @@ extern void frontswap_writethrough(bool); #define FRONTSWAP_HAS_EXCLUSIVE_GETS extern void frontswap_tmem_exclusive_gets(bool); -extern void __frontswap_init(unsigned type); +extern bool __frontswap_test(struct swap_info_struct *, pgoff_t); +extern void __frontswap_init(unsigned type, unsigned long *map); extern int __frontswap_store(struct page *page); extern int __frontswap_load(struct page *page); extern void __frontswap_invalidate_page(unsigned, pgoff_t); extern void __frontswap_invalidate_area(unsigned); #ifdef CONFIG_FRONTSWAP +#define frontswap_enabled (1) static inline bool frontswap_test(struct swap_info_struct *sis, pgoff_t offset) { - bool ret = false; - - if (frontswap_enabled && sis->frontswap_map) - ret = test_bit(offset, sis->frontswap_map); - return ret; -} - -static inline void frontswap_set(struct swap_info_struct *sis, pgoff_t offset) -{ - if (frontswap_enabled && sis->frontswap_map) - set_bit(offset, sis->frontswap_map); -} - -static inline void frontswap_clear(struct swap_info_struct *sis, pgoff_t offset) -{ - if (frontswap_enabled && sis->frontswap_map) - clear_bit(offset, sis->frontswap_map); + return __frontswap_test(sis, offset); } static inline void frontswap_map_set(struct swap_info_struct *p, @@ -71,14 +57,6 @@ static inline bool frontswap_test(struct swap_info_struct *sis, pgoff_t offset) return false; } -static inline void frontswap_set(struct swap_info_struct *sis, pgoff_t offset) -{ -} - -static inline void frontswap_clear(struct swap_info_struct *sis, pgoff_t offset) -{ -} - static inline void frontswap_map_set(struct swap_info_struct *p, unsigned long *map) { @@ -120,10 +98,10 @@ static inline void frontswap_invalidate_area(unsigned type) __frontswap_invalidate_area(type); } -static inline void frontswap_init(unsigned type) +static inline void frontswap_init(unsigned type, unsigned long *map) { if (frontswap_enabled) - __frontswap_init(type); + __frontswap_init(type, map); } #endif /* _LINUX_FRONTSWAP_H */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 74a907b8b950..4c743ed2e46e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -10,6 +10,8 @@ #include <linux/stat.h> #include <linux/cache.h> #include <linux/list.h> +#include <linux/list_lru.h> +#include <linux/llist.h> #include <linux/radix-tree.h> #include <linux/rbtree.h> #include <linux/init.h> @@ -45,6 +47,7 @@ struct vfsmount; struct cred; struct swap_info_struct; struct seq_file; +struct workqueue_struct; extern void __init inode_init(void); extern void __init inode_init_early(void); @@ -62,8 +65,7 @@ struct buffer_head; typedef int (get_block_t)(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create); typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, - ssize_t bytes, void *private, int ret, - bool is_async); + ssize_t bytes, void *private); #define MAY_EXEC 0x00000001 #define MAY_WRITE 0x00000002 @@ -180,8 +182,6 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, #define READ 0 #define WRITE RW_MASK #define READA RWA_MASK -#define KERNEL_READ (READ|REQ_KERNEL) -#define KERNEL_WRITE (WRITE|REQ_KERNEL) #define READ_SYNC (READ | REQ_SYNC) #define WRITE_SYNC (WRITE | REQ_SYNC | REQ_NOIDLE) @@ -289,25 +289,108 @@ struct address_space; struct writeback_control; struct iov_iter { - const struct iovec *iov; + struct iov_iter_ops *ops; + unsigned long data; unsigned long nr_segs; size_t iov_offset; size_t count; }; -size_t iov_iter_copy_from_user_atomic(struct page *page, - struct iov_iter *i, unsigned long offset, size_t bytes); -size_t iov_iter_copy_from_user(struct page *page, - struct iov_iter *i, unsigned long offset, size_t bytes); -void iov_iter_advance(struct iov_iter *i, size_t bytes); -int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); -size_t iov_iter_single_seg_count(const struct iov_iter *i); +struct iov_iter_ops { + size_t (*ii_copy_to_user_atomic)(struct page *, struct iov_iter *, + unsigned long, size_t); + size_t (*ii_copy_to_user)(struct page *, struct iov_iter *, + unsigned long, size_t, int); + size_t (*ii_copy_from_user_atomic)(struct page *, struct iov_iter *, + unsigned long, size_t); + size_t (*ii_copy_from_user)(struct page *, struct iov_iter *, + unsigned long, size_t); + void (*ii_advance)(struct iov_iter *, size_t); + int (*ii_fault_in_readable)(struct iov_iter *, size_t); + size_t (*ii_single_seg_count)(const struct iov_iter *); + int (*ii_shorten)(struct iov_iter *, size_t); +}; + +static inline size_t iov_iter_copy_to_user_atomic(struct page *page, + struct iov_iter *i, unsigned long offset, size_t bytes) +{ + return i->ops->ii_copy_to_user_atomic(page, i, offset, bytes); +} +static inline size_t __iov_iter_copy_to_user(struct page *page, + struct iov_iter *i, unsigned long offset, size_t bytes) +{ + return i->ops->ii_copy_to_user(page, i, offset, bytes, 0); +} +static inline size_t iov_iter_copy_to_user(struct page *page, + struct iov_iter *i, unsigned long offset, size_t bytes) +{ + return i->ops->ii_copy_to_user(page, i, offset, bytes, 1); +} +static inline size_t iov_iter_copy_from_user_atomic(struct page *page, + struct iov_iter *i, unsigned long offset, size_t bytes) +{ + return i->ops->ii_copy_from_user_atomic(page, i, offset, bytes); +} +static inline size_t iov_iter_copy_from_user(struct page *page, + struct iov_iter *i, unsigned long offset, size_t bytes) +{ + return i->ops->ii_copy_from_user(page, i, offset, bytes); +} +static inline void iov_iter_advance(struct iov_iter *i, size_t bytes) +{ + return i->ops->ii_advance(i, bytes); +} +static inline int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes) +{ + return i->ops->ii_fault_in_readable(i, bytes); +} +static inline size_t iov_iter_single_seg_count(const struct iov_iter *i) +{ + return i->ops->ii_single_seg_count(i); +} +static inline int iov_iter_shorten(struct iov_iter *i, size_t count) +{ + return i->ops->ii_shorten(i, count); +} + +#ifdef CONFIG_BLOCK +extern struct iov_iter_ops ii_bvec_ops; + +struct bio_vec; +static inline void iov_iter_init_bvec(struct iov_iter *i, + struct bio_vec *bvec, + unsigned long nr_segs, + size_t count, size_t written) +{ + i->ops = &ii_bvec_ops; + i->data = (unsigned long)bvec; + i->nr_segs = nr_segs; + i->iov_offset = 0; + i->count = count + written; + + iov_iter_advance(i, written); +} + +static inline int iov_iter_has_bvec(struct iov_iter *i) +{ + return i->ops == &ii_bvec_ops; +} + +static inline struct bio_vec *iov_iter_bvec(struct iov_iter *i) +{ + BUG_ON(!iov_iter_has_bvec(i)); + return (struct bio_vec *)i->data; +} +#endif + +extern struct iov_iter_ops ii_iovec_ops; static inline void iov_iter_init(struct iov_iter *i, const struct iovec *iov, unsigned long nr_segs, size_t count, size_t written) { - i->iov = iov; + i->ops = &ii_iovec_ops; + i->data = (unsigned long)iov; i->nr_segs = nr_segs; i->iov_offset = 0; i->count = count + written; @@ -315,6 +398,17 @@ static inline void iov_iter_init(struct iov_iter *i, iov_iter_advance(i, written); } +static inline int iov_iter_has_iovec(struct iov_iter *i) +{ + return i->ops == &ii_iovec_ops; +} + +static inline struct iovec *iov_iter_iovec(struct iov_iter *i) +{ + BUG_ON(!iov_iter_has_iovec(i)); + return (struct iovec *)i->data; +} + static inline size_t iov_iter_count(struct iov_iter *i) { return i->count; @@ -364,22 +458,23 @@ struct address_space_operations { /* Unfortunately this kludge is needed for FIBMAP. Don't use it */ sector_t (*bmap)(struct address_space *, sector_t); - void (*invalidatepage) (struct page *, unsigned long); + void (*invalidatepage) (struct page *, unsigned int, unsigned int); int (*releasepage) (struct page *, gfp_t); void (*freepage)(struct page *); - ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, - loff_t offset, unsigned long nr_segs); + ssize_t (*direct_IO)(int, struct kiocb *, struct iov_iter *iter, + loff_t offset); int (*get_xip_mem)(struct address_space *, pgoff_t, int, void **, unsigned long *); /* - * migrate the contents of a page to the specified target. If sync - * is false, it must not block. + * migrate the contents of a page to the specified target. If + * migrate_mode is MIGRATE_ASYNC, it must not block. */ int (*migratepage) (struct address_space *, struct page *, struct page *, enum migrate_mode); int (*launder_page) (struct page *); int (*is_partially_uptodate) (struct page *, read_descriptor_t *, unsigned long); + void (*is_dirty_writeback) (struct page *, bool *, bool *); int (*error_remove_page)(struct address_space *, struct page *); /* swapfile support */ @@ -675,9 +770,11 @@ static inline loff_t i_size_read(const struct inode *inode) static inline void i_size_write(struct inode *inode, loff_t i_size) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP) + preempt_disable(); write_seqcount_begin(&inode->i_size_seqcount); inode->i_size = i_size; write_seqcount_end(&inode->i_size_seqcount); + preempt_enable(); #elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPT) preempt_disable(); inode->i_size = i_size; @@ -765,6 +862,7 @@ struct file { */ union { struct list_head fu_list; + struct llist_node fu_llist; struct rcu_head fu_rcuhead; } f_u; struct path f_path; @@ -906,6 +1004,7 @@ struct file_lock_operations { struct lock_manager_operations { int (*lm_compare_owner)(struct file_lock *, struct file_lock *); + unsigned long (*lm_owner_key)(struct file_lock *); void (*lm_notify)(struct file_lock *); /* unblock callback */ int (*lm_grant)(struct file_lock *, struct file_lock *, int); void (*lm_break)(struct file_lock *); @@ -924,14 +1023,33 @@ int locks_in_grace(struct net *); /* that will die - we need it for nfs_lock_info */ #include <linux/nfs_fs_i.h> +/* + * struct file_lock represents a generic "file lock". It's used to represent + * POSIX byte range locks, BSD (flock) locks, and leases. It's important to + * note that the same struct is used to represent both a request for a lock and + * the lock itself, but the same object is never used for both. + * + * FIXME: should we create a separate "struct lock_request" to help distinguish + * these two uses? + * + * The i_flock list is ordered by: + * + * 1) lock type -- FL_LEASEs first, then FL_FLOCK, and finally FL_POSIX + * 2) lock owner + * 3) lock range start + * 4) lock range end + * + * Obviously, the last two criteria only matter for POSIX locks. + */ struct file_lock { struct file_lock *fl_next; /* singly linked list for this inode */ - struct list_head fl_link; /* doubly linked list of all locks */ + struct hlist_node fl_link; /* node in global lists */ struct list_head fl_block; /* circular list of blocked processes */ fl_owner_t fl_owner; unsigned int fl_flags; unsigned char fl_type; unsigned int fl_pid; + int fl_link_cpu; /* what cpu's list is this on? */ struct pid *fl_nspid; wait_queue_head_t fl_wait; struct file *fl_file; @@ -992,7 +1110,7 @@ extern void locks_release_private(struct file_lock *); extern void posix_test_lock(struct file *, struct file_lock *); extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *); extern int posix_lock_file_wait(struct file *, struct file_lock *); -extern int posix_unblock_lock(struct file *, struct file_lock *); +extern int posix_unblock_lock(struct file_lock *); extern int vfs_test_lock(struct file *, struct file_lock *); extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *); extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl); @@ -1004,9 +1122,6 @@ extern int vfs_setlease(struct file *, long, struct file_lock **); extern int lease_modify(struct file_lock **, int); extern int lock_may_read(struct inode *, loff_t start, unsigned long count); extern int lock_may_write(struct inode *, loff_t start, unsigned long count); -extern void locks_delete_block(struct file_lock *waiter); -extern void lock_flocks(void); -extern void unlock_flocks(void); #else /* !CONFIG_FILE_LOCKING */ static inline int fcntl_getlk(struct file *file, struct flock __user *user) { @@ -1082,8 +1197,7 @@ static inline int posix_lock_file_wait(struct file *filp, struct file_lock *fl) return -ENOLCK; } -static inline int posix_unblock_lock(struct file *filp, - struct file_lock *waiter) +static inline int posix_unblock_lock(struct file_lock *waiter) { return -ENOENT; } @@ -1148,19 +1262,6 @@ static inline int lock_may_write(struct inode *inode, loff_t start, { return 1; } - -static inline void locks_delete_block(struct file_lock *waiter) -{ -} - -static inline void lock_flocks(void) -{ -} - -static inline void unlock_flocks(void) -{ -} - #endif /* !CONFIG_FILE_LOCKING */ @@ -1261,15 +1362,6 @@ struct super_block { struct list_head s_files; #endif struct list_head s_mounts; /* list of mounts; _not_ for fs use */ - /* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */ - struct list_head s_dentry_lru; /* unused dentry lru */ - int s_nr_dentry_unused; /* # of dentry on lru */ - - /* s_inode_lru_lock protects s_inode_lru and s_nr_inodes_unused */ - spinlock_t s_inode_lru_lock ____cacheline_aligned_in_smp; - struct list_head s_inode_lru; /* unused inode lru */ - int s_nr_inodes_unused; /* # of inodes on lru */ - struct block_device *s_bdev; struct backing_dev_info *s_bdi; struct mtd_info *s_mtd; @@ -1320,11 +1412,17 @@ struct super_block { /* Being remounted read-only */ int s_readonly_remount; -}; -/* superblock cache pruning functions */ -extern void prune_icache_sb(struct super_block *sb, int nr_to_scan); -extern void prune_dcache_sb(struct super_block *sb, int nr_to_scan); + /* AIO completions deferred from interrupt context */ + struct workqueue_struct *s_dio_done_wq; + + /* + * Keep the lru lists last in the structure so they always sit on their + * own individual cachelines. + */ + struct list_lru s_dentry_lru ____cacheline_aligned_in_smp; + struct list_lru s_inode_lru ____cacheline_aligned_in_smp; +}; extern struct timespec current_fs_time(struct super_block *sb); @@ -1504,6 +1602,11 @@ int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags); * to have different dirent layouts depending on the binary type. */ typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned); +struct dir_context { + const filldir_t actor; + loff_t pos; +}; + struct block_device_operations; /* These macros are for out of kernel modules to test that @@ -1518,8 +1621,10 @@ struct file_operations { ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); + ssize_t (*read_iter) (struct kiocb *, struct iov_iter *, loff_t); ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); - int (*readdir) (struct file *, void *, filldir_t); + ssize_t (*write_iter) (struct kiocb *, struct iov_iter *, loff_t); + int (*iterate) (struct file *, struct dir_context *); unsigned int (*poll) (struct file *, struct poll_table_struct *); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); @@ -1543,6 +1648,18 @@ struct file_operations { int (*show_fdinfo)(struct seq_file *m, struct file *f); }; +static inline int file_readable(struct file *filp) +{ + return filp && (filp->f_op->read || filp->f_op->aio_read || + filp->f_op->read_iter); +} + +static inline int file_writable(struct file *filp) +{ + return filp && (filp->f_op->write || filp->f_op->aio_write || + filp->f_op->write_iter); +} + struct inode_operations { struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int); void * (*follow_link) (struct dentry *, struct nameidata *); @@ -1573,6 +1690,7 @@ struct inode_operations { int (*atomic_open)(struct inode *, struct dentry *, struct file *, unsigned open_flag, umode_t create_mode, int *opened); + int (*tmpfile) (struct inode *, struct dentry *, umode_t); } ____cacheline_aligned; ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, @@ -1612,8 +1730,8 @@ struct super_operations { ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); #endif int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t); - int (*nr_cached_objects)(struct super_block *); - void (*free_cached_objects)(struct super_block *, int); + long (*nr_cached_objects)(struct super_block *, int); + long (*free_cached_objects)(struct super_block *, long, int); }; /* @@ -1736,6 +1854,7 @@ struct super_operations { #define I_REFERENCED (1 << 8) #define __I_DIO_WAKEUP 9 #define I_DIO_WAKEUP (1 << I_DIO_WAKEUP) +#define I_LINKABLE (1 << 10) #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) @@ -1789,7 +1908,7 @@ enum file_time_flags { S_VERSION = 8, }; -extern void touch_atime(struct path *); +extern void touch_atime(const struct path *); static inline void file_accessed(struct file *file) { if (!(file->f_flags & O_NOATIME)) @@ -1825,6 +1944,8 @@ struct file_system_type { struct lock_class_key i_mutex_dir_key; }; +#define MODULE_ALIAS_FS(NAME) MODULE_ALIAS("fs-" NAME) + extern struct dentry *mount_ns(struct file_system_type *fs_type, int flags, void *data, int (*fill_super)(struct super_block *, void *, int)); extern struct dentry *mount_bdev(struct file_system_type *fs_type, @@ -1880,6 +2001,7 @@ extern int vfs_ustat(dev_t, struct kstatfs *); extern int freeze_super(struct super_block *super); extern int thaw_super(struct super_block *super); extern bool our_mnt(struct vfsmount *mnt); +extern bool fs_fully_visible(struct file_system_type *); extern int current_umask(void); @@ -1887,7 +2009,6 @@ extern int current_umask(void); extern struct kobject *fs_kobj; #define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK) -extern int rw_verify_area(int, struct file *, loff_t *, size_t); #define FLOCK_VERIFY_READ 1 #define FLOCK_VERIFY_WRITE 2 @@ -2054,6 +2175,7 @@ extern struct super_block *freeze_bdev(struct block_device *); extern void emergency_thaw_all(void); extern int thaw_bdev(struct block_device *bdev, struct super_block *sb); extern int fsync_bdev(struct block_device *); +extern int sb_is_blkdev_sb(struct super_block *sb); #else static inline void bd_forget(struct inode *inode) {} static inline int sync_blockdev(struct block_device *bdev) { return 0; } @@ -2073,12 +2195,16 @@ static inline int thaw_bdev(struct block_device *bdev, struct super_block *sb) static inline void iterate_bdevs(void (*f)(struct block_device *, void *), void *arg) { } + +static inline int sb_is_blkdev_sb(struct super_block *sb) +{ + return 0; +} #endif extern int sync_filesystem(struct super_block *); extern const struct file_operations def_blk_fops; extern const struct file_operations def_chr_fops; extern const struct file_operations bad_sock_fops; -extern const struct file_operations def_fifo_fops; #ifdef CONFIG_BLOCK extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); @@ -2088,7 +2214,7 @@ extern struct block_device *blkdev_get_by_path(const char *path, fmode_t mode, void *holder); extern struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder); -extern int blkdev_put(struct block_device *bdev, fmode_t mode); +extern void blkdev_put(struct block_device *bdev, fmode_t mode); #ifdef CONFIG_SYSFS extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk); extern void bd_unlink_disk_holder(struct block_device *bdev, @@ -2150,10 +2276,6 @@ extern void init_special_inode(struct inode *, umode_t, dev_t); extern void make_bad_inode(struct inode *); extern int is_bad_inode(struct inode *); -extern const struct file_operations read_pipefifo_fops; -extern const struct file_operations write_pipefifo_fops; -extern const struct file_operations rdwr_pipefifo_fops; - #ifdef CONFIG_BLOCK /* * return READ, READA, or WRITE @@ -2221,6 +2343,27 @@ static inline struct inode *file_inode(struct file *f) return f->f_inode; } +static inline void file_start_write(struct file *file) +{ + if (!S_ISREG(file_inode(file)->i_mode)) + return; + __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, true); +} + +static inline bool file_start_write_trylock(struct file *file) +{ + if (!S_ISREG(file_inode(file)->i_mode)) + return true; + return __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, false); +} + +static inline void file_end_write(struct file *file) +{ + if (!S_ISREG(file_inode(file)->i_mode)) + return; + __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE); +} + /* * get_write_access() gets write permission for a file. * put_write_access() releases this write permission. @@ -2255,6 +2398,11 @@ static inline void allow_write_access(struct file *file) if (file) atomic_inc(&file_inode(file)->i_writecount); } +static inline bool inode_is_open_for_write(const struct inode *inode) +{ + return atomic_read(&inode->i_writecount) > 0; +} + #ifdef CONFIG_IMA static inline void i_readcount_dec(struct inode *inode) { @@ -2284,7 +2432,6 @@ extern struct file * open_exec(const char *); /* fs/dcache.c -- generic fs support functions */ extern int is_subdir(struct dentry *, struct dentry *); extern int path_is_under(struct path *, struct path *); -extern ino_t find_inode_number(struct dentry *, struct qstr *); #include <linux/err.h> @@ -2362,25 +2509,36 @@ extern int sb_min_blocksize(struct super_block *, int); extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); extern int generic_file_remap_pages(struct vm_area_struct *, unsigned long addr, - unsigned long size, pgoff_t pgoff); -extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size); + unsigned long size, pgoff_t pgoff); +extern int file_read_iter_actor(read_descriptor_t *desc, struct page *page, + unsigned long offset, unsigned long size); int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk); extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t); +extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *, + loff_t); extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t *); +extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *, + loff_t *); extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t); +extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *, + loff_t); extern ssize_t generic_file_direct_write(struct kiocb *, const struct iovec *, unsigned long *, loff_t, loff_t *, size_t, size_t); +extern ssize_t generic_file_direct_write_iter(struct kiocb *, struct iov_iter *, + loff_t, loff_t *, size_t); extern ssize_t generic_file_buffered_write(struct kiocb *, const struct iovec *, unsigned long, loff_t, loff_t *, size_t, ssize_t); +extern ssize_t generic_file_buffered_write_iter(struct kiocb *, + struct iov_iter *, loff_t, loff_t *, size_t, ssize_t); extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos); extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); extern int generic_segment_checks(const struct iovec *iov, unsigned long *nr_segs, size_t *count, int access_flags); /* fs/block_dev.c */ -extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t pos); +extern ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *iter, + loff_t pos); extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end, int datasync); extern void block_sync_page(struct page *page); @@ -2394,16 +2552,17 @@ extern ssize_t generic_file_splice_write(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, loff_t *, size_t len, unsigned int flags); -extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, - size_t len, unsigned int flags); extern void file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); extern loff_t noop_llseek(struct file *file, loff_t offset, int whence); extern loff_t no_llseek(struct file *file, loff_t offset, int whence); +extern loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize); extern loff_t generic_file_llseek(struct file *file, loff_t offset, int whence); extern loff_t generic_file_llseek_size(struct file *file, loff_t offset, int whence, loff_t maxsize, loff_t eof); +extern loff_t fixed_size_llseek(struct file *file, loff_t offset, + int whence, loff_t size); extern int generic_file_open(struct inode * inode, struct file * filp); extern int nonseekable_open(struct inode * inode, struct file * filp); @@ -2436,16 +2595,16 @@ enum { void dio_end_io(struct bio *bio, int error); ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, - struct block_device *bdev, const struct iovec *iov, loff_t offset, - unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io, - dio_submit_t submit_io, int flags); + struct block_device *bdev, struct iov_iter *iter, loff_t offset, + get_block_t get_block, dio_iodone_t end_io, dio_submit_t submit_io, + int flags); static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb, - struct inode *inode, const struct iovec *iov, loff_t offset, - unsigned long nr_segs, get_block_t get_block) + struct inode *inode, struct iov_iter *iter, loff_t offset, + get_block_t get_block) { - return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, - offset, nr_segs, get_block, NULL, NULL, + return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iter, + offset, get_block, NULL, NULL, DIO_LOCKING | DIO_SKIP_HOLES); } #endif @@ -2458,7 +2617,6 @@ extern const struct file_operations generic_ro_fops; #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) extern int vfs_readlink(struct dentry *, char __user *, int, const char *); -extern int vfs_follow_link(struct nameidata *, const char *); extern int page_readlink(struct dentry *, char __user *, int); extern void *page_follow_link_light(struct dentry *, struct nameidata *); extern void page_put_link(struct dentry *, struct nameidata *, void *); @@ -2466,16 +2624,19 @@ extern int __page_symlink(struct inode *inode, const char *symname, int len, int nofs); extern int page_symlink(struct inode *inode, const char *symname, int len); extern const struct inode_operations page_symlink_inode_operations; +extern void kfree_put_link(struct dentry *, struct nameidata *, void *); extern int generic_readlink(struct dentry *, char __user *, int); extern void generic_fillattr(struct inode *, struct kstat *); extern int vfs_getattr(struct path *, struct kstat *); void __inode_add_bytes(struct inode *inode, loff_t bytes); void inode_add_bytes(struct inode *inode, loff_t bytes); +void __inode_sub_bytes(struct inode *inode, loff_t bytes); void inode_sub_bytes(struct inode *inode, loff_t bytes); loff_t inode_get_bytes(struct inode *inode); void inode_set_bytes(struct inode *inode, loff_t bytes); extern int vfs_readdir(struct file *, filldir_t, void *); +extern int iterate_dir(struct file *, struct dir_context *); extern int vfs_stat(const char __user *, struct kstat *); extern int vfs_lstat(const char __user *, struct kstat *); @@ -2506,7 +2667,7 @@ extern void iterate_supers_type(struct file_system_type *, extern int dcache_dir_open(struct inode *, struct file *); extern int dcache_dir_close(struct inode *, struct file *); extern loff_t dcache_dir_lseek(struct file *, loff_t, int); -extern int dcache_readdir(struct file *, void *, filldir_t); +extern int dcache_readdir(struct file *, struct dir_context *); extern int simple_setattr(struct dentry *, struct iattr *); extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int simple_statfs(struct dentry *, struct kstatfs *); @@ -2670,4 +2831,41 @@ static inline void inode_has_no_xattr(struct inode *inode) inode->i_flags |= S_NOSEC; } +static inline bool dir_emit(struct dir_context *ctx, + const char *name, int namelen, + u64 ino, unsigned type) +{ + return ctx->actor(ctx, name, namelen, ctx->pos, ino, type) == 0; +} +static inline bool dir_emit_dot(struct file *file, struct dir_context *ctx) +{ + return ctx->actor(ctx, ".", 1, ctx->pos, + file->f_path.dentry->d_inode->i_ino, DT_DIR) == 0; +} +static inline bool dir_emit_dotdot(struct file *file, struct dir_context *ctx) +{ + return ctx->actor(ctx, "..", 2, ctx->pos, + parent_ino(file->f_path.dentry), DT_DIR) == 0; +} +static inline bool dir_emit_dots(struct file *file, struct dir_context *ctx) +{ + if (ctx->pos == 0) { + if (!dir_emit_dot(file, ctx)) + return false; + ctx->pos = 1; + } + if (ctx->pos == 1) { + if (!dir_emit_dotdot(file, ctx)) + return false; + ctx->pos = 2; + } + return true; +} +static inline bool dir_relax(struct inode *inode) +{ + mutex_unlock(&inode->i_mutex); + mutex_lock(&inode->i_mutex); + return !IS_DEADDIR(inode); +} + #endif /* _LINUX_FS_H */ diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h index 51b793466ff3..efb05961bdd8 100644 --- a/include/linux/fs_enet_pd.h +++ b/include/linux/fs_enet_pd.h @@ -16,8 +16,10 @@ #ifndef FS_ENET_PD_H #define FS_ENET_PD_H +#include <linux/clk.h> #include <linux/string.h> #include <linux/of_mdio.h> +#include <linux/if_ether.h> #include <asm/types.h> #define FS_ENET_NAME "fs_enet" @@ -135,13 +137,15 @@ struct fs_platform_info { const struct fs_mii_bus_info *bus_info; int rx_ring, tx_ring; /* number of buffers on rx */ - __u8 macaddr[6]; /* mac address */ + __u8 macaddr[ETH_ALEN]; /* mac address */ int rx_copybreak; /* limit we copy small frames */ int use_napi; /* use NAPI */ int napi_weight; /* NAPI weight */ int use_rmii; /* use RMII mode */ int has_phy; /* if the network is phy container as well...*/ + + struct clk *clk_per; /* 'per' clock for register access */ }; struct fs_mii_fec_platform_info { u32 irq[32]; diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index 729eded4b24f..0efc3e62843a 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h @@ -39,15 +39,6 @@ static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd) spin_unlock(&fs->lock); } -static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root, - struct path *pwd) -{ - spin_lock(&fs->lock); - *root = fs->root; - path_get(root); - *pwd = fs->pwd; - path_get(pwd); - spin_unlock(&fs->lock); -} +extern bool current_chrooted(void); #endif /* _LINUX_FS_STRUCT_H */ diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 5dfa0aa216b6..771484993ca7 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -97,7 +97,8 @@ struct fscache_operation { #define FSCACHE_OP_WAITING 4 /* cleared when op is woken */ #define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */ #define FSCACHE_OP_DEC_READ_CNT 6 /* decrement object->n_reads on destruction */ -#define FSCACHE_OP_KEEP_FLAGS 0x0070 /* flags to keep when repurposing an op */ +#define FSCACHE_OP_UNUSE_COOKIE 7 /* call fscache_unuse_cookie() on completion */ +#define FSCACHE_OP_KEEP_FLAGS 0x00f0 /* flags to keep when repurposing an op */ enum fscache_operation_state state; atomic_t usage; @@ -150,7 +151,7 @@ struct fscache_retrieval { void *context; /* netfs read context (pinned) */ struct list_head to_do; /* list of things to be done by the backend */ unsigned long start_time; /* time at which retrieval started */ - unsigned n_pages; /* number of pages to be retrieved */ + atomic_t n_pages; /* number of pages to be retrieved */ }; typedef int (*fscache_page_retrieval_func_t)(struct fscache_retrieval *op, @@ -194,15 +195,14 @@ static inline void fscache_enqueue_retrieval(struct fscache_retrieval *op) static inline void fscache_retrieval_complete(struct fscache_retrieval *op, int n_pages) { - op->n_pages -= n_pages; - if (op->n_pages <= 0) + atomic_sub(n_pages, &op->n_pages); + if (atomic_read(&op->n_pages) <= 0) fscache_op_complete(&op->op, true); } /** * fscache_put_retrieval - Drop a reference to a retrieval operation * @op: The retrieval operation affected - * @n_pages: The number of pages to account for * * Drop a reference to a retrieval operation. */ @@ -251,6 +251,10 @@ struct fscache_cache_ops { /* unpin an object in the cache */ void (*unpin_object)(struct fscache_object *object); + /* check the consistency between the backing cache and the FS-Cache + * cookie */ + bool (*check_consistency)(struct fscache_operation *op); + /* store the updated auxiliary data on an object */ void (*update_object)(struct fscache_object *object); @@ -304,82 +308,46 @@ struct fscache_cache_ops { void (*dissociate_pages)(struct fscache_cache *cache); }; -/* - * data file or index object cookie - * - a file will only appear in one cache - * - a request to cache a file may or may not be honoured, subject to - * constraints such as disk space - * - indices are created on disk just-in-time - */ -struct fscache_cookie { - atomic_t usage; /* number of users of this cookie */ - atomic_t n_children; /* number of children of this cookie */ - spinlock_t lock; - spinlock_t stores_lock; /* lock on page store tree */ - struct hlist_head backing_objects; /* object(s) backing this file/index */ - const struct fscache_cookie_def *def; /* definition */ - struct fscache_cookie *parent; /* parent of this entry */ - void *netfs_data; /* back pointer to netfs */ - struct radix_tree_root stores; /* pages to be stored on this cookie */ -#define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */ -#define FSCACHE_COOKIE_STORING_TAG 1 /* pages tag: writing to cache */ - - unsigned long flags; -#define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ -#define FSCACHE_COOKIE_CREATING 1 /* T if non-index object being created still */ -#define FSCACHE_COOKIE_NO_DATA_YET 2 /* T if new object with no cached data yet */ -#define FSCACHE_COOKIE_PENDING_FILL 3 /* T if pending initial fill on object */ -#define FSCACHE_COOKIE_FILLING 4 /* T if filling object incrementally */ -#define FSCACHE_COOKIE_UNAVAILABLE 5 /* T if cookie is unavailable (error, etc) */ -#define FSCACHE_COOKIE_WAITING_ON_READS 6 /* T if cookie is waiting on reads */ -#define FSCACHE_COOKIE_INVALIDATING 7 /* T if cookie is being invalidated */ -}; - extern struct fscache_cookie fscache_fsdef_index; /* * Event list for fscache_object::{event_mask,events} */ enum { - FSCACHE_OBJECT_EV_REQUEUE, /* T if object should be requeued */ + FSCACHE_OBJECT_EV_NEW_CHILD, /* T if object has a new child */ + FSCACHE_OBJECT_EV_PARENT_READY, /* T if object's parent is ready */ FSCACHE_OBJECT_EV_UPDATE, /* T if object should be updated */ FSCACHE_OBJECT_EV_INVALIDATE, /* T if cache requested object invalidation */ FSCACHE_OBJECT_EV_CLEARED, /* T if accessors all gone */ FSCACHE_OBJECT_EV_ERROR, /* T if fatal error occurred during processing */ - FSCACHE_OBJECT_EV_RELEASE, /* T if netfs requested object release */ - FSCACHE_OBJECT_EV_RETIRE, /* T if netfs requested object retirement */ - FSCACHE_OBJECT_EV_WITHDRAW, /* T if cache requested object withdrawal */ + FSCACHE_OBJECT_EV_KILL, /* T if netfs relinquished or cache withdrew object */ NR_FSCACHE_OBJECT_EVENTS }; #define FSCACHE_OBJECT_EVENTS_MASK ((1UL << NR_FSCACHE_OBJECT_EVENTS) - 1) /* + * States for object state machine. + */ +struct fscache_transition { + unsigned long events; + const struct fscache_state *transit_to; +}; + +struct fscache_state { + char name[24]; + char short_name[8]; + const struct fscache_state *(*work)(struct fscache_object *object, + int event); + const struct fscache_transition transitions[]; +}; + +/* * on-disk cache file or index handle */ struct fscache_object { - enum fscache_object_state { - FSCACHE_OBJECT_INIT, /* object in initial unbound state */ - FSCACHE_OBJECT_LOOKING_UP, /* looking up object */ - FSCACHE_OBJECT_CREATING, /* creating object */ - - /* active states */ - FSCACHE_OBJECT_AVAILABLE, /* cleaning up object after creation */ - FSCACHE_OBJECT_ACTIVE, /* object is usable */ - FSCACHE_OBJECT_INVALIDATING, /* object is invalidating */ - FSCACHE_OBJECT_UPDATING, /* object is updating */ - - /* terminal states */ - FSCACHE_OBJECT_DYING, /* object waiting for accessors to finish */ - FSCACHE_OBJECT_LC_DYING, /* object cleaning up after lookup/create */ - FSCACHE_OBJECT_ABORT_INIT, /* abort the init state */ - FSCACHE_OBJECT_RELEASING, /* releasing object */ - FSCACHE_OBJECT_RECYCLING, /* retiring object */ - FSCACHE_OBJECT_WITHDRAWING, /* withdrawing object */ - FSCACHE_OBJECT_DEAD, /* object is now dead */ - FSCACHE_OBJECT__NSTATES - } state; - + const struct fscache_state *state; /* Object state machine state */ + const struct fscache_transition *oob_table; /* OOB state transition table */ int debug_id; /* debugging ID */ int n_children; /* number of child objects */ int n_ops; /* number of extant ops on object */ @@ -390,6 +358,7 @@ struct fscache_object { spinlock_t lock; /* state and operations lock */ unsigned long lookup_jif; /* time at which lookup started */ + unsigned long oob_event_mask; /* OOB events this object is interested in */ unsigned long event_mask; /* events this object is interested in */ unsigned long events; /* events to be processed by this object * (order is important - using fls) */ @@ -398,6 +367,10 @@ struct fscache_object { #define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */ #define FSCACHE_OBJECT_PENDING_WRITE 1 /* T if object has pending write */ #define FSCACHE_OBJECT_WAITING 2 /* T if object is waiting on its parent */ +#define FSCACHE_OBJECT_IS_LIVE 3 /* T if object is not withdrawn or relinquished */ +#define FSCACHE_OBJECT_IS_LOOKED_UP 4 /* T if object has been looked up */ +#define FSCACHE_OBJECT_IS_AVAILABLE 5 /* T if object has become active */ +#define FSCACHE_OBJECT_RETIRED 6 /* T if object was retired on relinquishment */ struct list_head cache_link; /* link in cache->object_list */ struct hlist_node cookie_link; /* link in cookie->backing_objects */ @@ -415,62 +388,40 @@ struct fscache_object { loff_t store_limit_l; /* current storage limit */ }; -extern const char *fscache_object_states[]; +extern void fscache_object_init(struct fscache_object *, struct fscache_cookie *, + struct fscache_cache *); +extern void fscache_object_destroy(struct fscache_object *); -#define fscache_object_is_active(obj) \ - (!test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) && \ - (obj)->state >= FSCACHE_OBJECT_AVAILABLE && \ - (obj)->state < FSCACHE_OBJECT_DYING) +extern void fscache_object_lookup_negative(struct fscache_object *object); +extern void fscache_obtained_object(struct fscache_object *object); -#define fscache_object_is_dead(obj) \ - (test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) && \ - (obj)->state >= FSCACHE_OBJECT_DYING) +static inline bool fscache_object_is_live(struct fscache_object *object) +{ + return test_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags); +} -extern void fscache_object_work_func(struct work_struct *work); +static inline bool fscache_object_is_dying(struct fscache_object *object) +{ + return !fscache_object_is_live(object); +} -/** - * fscache_object_init - Initialise a cache object description - * @object: Object description - * - * Initialise a cache object description to its basic values. - * - * See Documentation/filesystems/caching/backend-api.txt for a complete - * description. - */ -static inline -void fscache_object_init(struct fscache_object *object, - struct fscache_cookie *cookie, - struct fscache_cache *cache) +static inline bool fscache_object_is_available(struct fscache_object *object) { - atomic_inc(&cache->object_count); - - object->state = FSCACHE_OBJECT_INIT; - spin_lock_init(&object->lock); - INIT_LIST_HEAD(&object->cache_link); - INIT_HLIST_NODE(&object->cookie_link); - INIT_WORK(&object->work, fscache_object_work_func); - INIT_LIST_HEAD(&object->dependents); - INIT_LIST_HEAD(&object->dep_link); - INIT_LIST_HEAD(&object->pending_ops); - object->n_children = 0; - object->n_ops = object->n_in_progress = object->n_exclusive = 0; - object->events = object->event_mask = 0; - object->flags = 0; - object->store_limit = 0; - object->store_limit_l = 0; - object->cache = cache; - object->cookie = cookie; - object->parent = NULL; + return test_bit(FSCACHE_OBJECT_IS_AVAILABLE, &object->flags); } -extern void fscache_object_lookup_negative(struct fscache_object *object); -extern void fscache_obtained_object(struct fscache_object *object); +static inline bool fscache_object_is_active(struct fscache_object *object) +{ + return fscache_object_is_available(object) && + fscache_object_is_live(object) && + !test_bit(FSCACHE_IOERROR, &object->cache->flags); +} -#ifdef CONFIG_FSCACHE_OBJECT_LIST -extern void fscache_object_destroy(struct fscache_object *object); -#else -#define fscache_object_destroy(object) do {} while(0) -#endif +static inline bool fscache_object_is_dead(struct fscache_object *object) +{ + return fscache_object_is_dying(object) && + test_bit(FSCACHE_IOERROR, &object->cache->flags); +} /** * fscache_object_destroyed - Note destruction of an object in a cache @@ -531,6 +482,48 @@ static inline void fscache_end_io(struct fscache_retrieval *op, op->end_io_func(page, op->context, error); } +static inline void __fscache_use_cookie(struct fscache_cookie *cookie) +{ + atomic_inc(&cookie->n_active); +} + +/** + * fscache_use_cookie - Request usage of cookie attached to an object + * @object: Object description + * + * Request usage of the cookie attached to an object. NULL is returned if the + * relinquishment had reduced the cookie usage count to 0. + */ +static inline bool fscache_use_cookie(struct fscache_object *object) +{ + struct fscache_cookie *cookie = object->cookie; + return atomic_inc_not_zero(&cookie->n_active) != 0; +} + +static inline bool __fscache_unuse_cookie(struct fscache_cookie *cookie) +{ + return atomic_dec_and_test(&cookie->n_active); +} + +static inline void __fscache_wake_unused_cookie(struct fscache_cookie *cookie) +{ + wake_up_atomic_t(&cookie->n_active); +} + +/** + * fscache_unuse_cookie - Cease usage of cookie attached to an object + * @object: Object description + * + * Cease usage of the cookie attached to an object. When the users count + * reaches zero then the cookie relinquishment will be permitted to proceed. + */ +static inline void fscache_unuse_cookie(struct fscache_object *object) +{ + struct fscache_cookie *cookie = object->cookie; + if (__fscache_unuse_cookie(cookie)) + __fscache_wake_unused_cookie(cookie); +} + /* * out-of-line cache backend functions */ diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 7a086235da4b..115bb81912cc 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -167,6 +167,42 @@ struct fscache_netfs { }; /* + * data file or index object cookie + * - a file will only appear in one cache + * - a request to cache a file may or may not be honoured, subject to + * constraints such as disk space + * - indices are created on disk just-in-time + */ +struct fscache_cookie { + atomic_t usage; /* number of users of this cookie */ + atomic_t n_children; /* number of children of this cookie */ + atomic_t n_active; /* number of active users of netfs ptrs */ + spinlock_t lock; + spinlock_t stores_lock; /* lock on page store tree */ + struct hlist_head backing_objects; /* object(s) backing this file/index */ + const struct fscache_cookie_def *def; /* definition */ + struct fscache_cookie *parent; /* parent of this entry */ + void *netfs_data; /* back pointer to netfs */ + struct radix_tree_root stores; /* pages to be stored on this cookie */ +#define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */ +#define FSCACHE_COOKIE_STORING_TAG 1 /* pages tag: writing to cache */ + + unsigned long flags; +#define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ +#define FSCACHE_COOKIE_NO_DATA_YET 1 /* T if new object with no cached data yet */ +#define FSCACHE_COOKIE_UNAVAILABLE 2 /* T if cookie is unavailable (error, etc) */ +#define FSCACHE_COOKIE_INVALIDATING 3 /* T if cookie is being invalidated */ +#define FSCACHE_COOKIE_RELINQUISHED 4 /* T if cookie has been relinquished */ +#define FSCACHE_COOKIE_ENABLED 5 /* T if cookie is enabled */ +#define FSCACHE_COOKIE_ENABLEMENT_LOCK 6 /* T if cookie is being en/disabled */ +}; + +static inline bool fscache_cookie_enabled(struct fscache_cookie *cookie) +{ + return test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); +} + +/* * slow-path functions for when there is actually caching available, and the * netfs does actually have a valid token * - these are not to be called directly @@ -181,8 +217,9 @@ extern void __fscache_release_cache_tag(struct fscache_cache_tag *); extern struct fscache_cookie *__fscache_acquire_cookie( struct fscache_cookie *, const struct fscache_cookie_def *, - void *); -extern void __fscache_relinquish_cookie(struct fscache_cookie *, int); + void *, bool); +extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool); +extern int __fscache_check_consistency(struct fscache_cookie *); extern void __fscache_update_cookie(struct fscache_cookie *); extern int __fscache_attr_changed(struct fscache_cookie *); extern void __fscache_invalidate(struct fscache_cookie *); @@ -208,6 +245,11 @@ extern bool __fscache_maybe_release_page(struct fscache_cookie *, struct page *, gfp_t); extern void __fscache_uncache_all_inode_pages(struct fscache_cookie *, struct inode *); +extern void __fscache_readpages_cancel(struct fscache_cookie *cookie, + struct list_head *pages); +extern void __fscache_disable_cookie(struct fscache_cookie *, bool); +extern void __fscache_enable_cookie(struct fscache_cookie *, + bool (*)(void *), void *); /** * fscache_register_netfs - Register a filesystem as desiring caching services @@ -286,6 +328,7 @@ void fscache_release_cache_tag(struct fscache_cache_tag *tag) * @def: A description of the cache object, including callback operations * @netfs_data: An arbitrary piece of data to be kept in the cookie to * represent the cache object to the netfs + * @enable: Whether or not to enable a data cookie immediately * * This function is used to inform FS-Cache about part of an index hierarchy * that can be used to locate files. This is done by requesting a cookie for @@ -298,10 +341,12 @@ static inline struct fscache_cookie *fscache_acquire_cookie( struct fscache_cookie *parent, const struct fscache_cookie_def *def, - void *netfs_data) + void *netfs_data, + bool enable) { - if (fscache_cookie_valid(parent)) - return __fscache_acquire_cookie(parent, def, netfs_data); + if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent)) + return __fscache_acquire_cookie(parent, def, netfs_data, + enable); else return NULL; } @@ -319,13 +364,32 @@ struct fscache_cookie *fscache_acquire_cookie( * description. */ static inline -void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) +void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire) { if (fscache_cookie_valid(cookie)) __fscache_relinquish_cookie(cookie, retire); } /** + * fscache_check_consistency - Request that if the cache is updated + * @cookie: The cookie representing the cache object + * + * Request an consistency check from fscache, which passes the request + * to the backing cache. + * + * Returns 0 if consistent and -ESTALE if inconsistent. May also + * return -ENOMEM and -ERESTARTSYS. + */ +static inline +int fscache_check_consistency(struct fscache_cookie *cookie) +{ + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) + return __fscache_check_consistency(cookie); + else + return 0; +} + +/** * fscache_update_cookie - Request that a cache object be updated * @cookie: The cookie representing the cache object * @@ -338,7 +402,7 @@ void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) static inline void fscache_update_cookie(struct fscache_cookie *cookie) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) __fscache_update_cookie(cookie); } @@ -385,7 +449,7 @@ void fscache_unpin_cookie(struct fscache_cookie *cookie) static inline int fscache_attr_changed(struct fscache_cookie *cookie) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) return __fscache_attr_changed(cookie); else return -ENOBUFS; @@ -407,7 +471,7 @@ int fscache_attr_changed(struct fscache_cookie *cookie) static inline void fscache_invalidate(struct fscache_cookie *cookie) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) __fscache_invalidate(cookie); } @@ -481,7 +545,7 @@ int fscache_read_or_alloc_page(struct fscache_cookie *cookie, void *context, gfp_t gfp) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) return __fscache_read_or_alloc_page(cookie, page, end_io_func, context, gfp); else @@ -532,7 +596,7 @@ int fscache_read_or_alloc_pages(struct fscache_cookie *cookie, void *context, gfp_t gfp) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) return __fscache_read_or_alloc_pages(cookie, mapping, pages, nr_pages, end_io_func, context, gfp); @@ -563,13 +627,33 @@ int fscache_alloc_page(struct fscache_cookie *cookie, struct page *page, gfp_t gfp) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) return __fscache_alloc_page(cookie, page, gfp); else return -ENOBUFS; } /** + * fscache_readpages_cancel - Cancel read/alloc on pages + * @cookie: The cookie representing the inode's cache object. + * @pages: The netfs pages that we canceled write on in readpages() + * + * Uncache/unreserve the pages reserved earlier in readpages() via + * fscache_readpages_or_alloc() and similar. In most successful caches in + * readpages() this doesn't do anything. In cases when the underlying netfs's + * readahead failed we need to clean up the pagelist (unmark and uncache). + * + * This function may sleep as it may have to clean up disk state. + */ +static inline +void fscache_readpages_cancel(struct fscache_cookie *cookie, + struct list_head *pages) +{ + if (fscache_cookie_valid(cookie)) + __fscache_readpages_cancel(cookie, pages); +} + +/** * fscache_write_page - Request storage of a page in the cache * @cookie: The cookie representing the cache object * @page: The netfs page to store @@ -592,7 +676,7 @@ int fscache_write_page(struct fscache_cookie *cookie, struct page *page, gfp_t gfp) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) return __fscache_write_page(cookie, page, gfp); else return -ENOBUFS; @@ -702,4 +786,47 @@ void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, __fscache_uncache_all_inode_pages(cookie, inode); } +/** + * fscache_disable_cookie - Disable a cookie + * @cookie: The cookie representing the cache object + * @invalidate: Invalidate the backing object + * + * Disable a cookie from accepting further alloc, read, write, invalidate, + * update or acquire operations. Outstanding operations can still be waited + * upon and pages can still be uncached and the cookie relinquished. + * + * This will not return until all outstanding operations have completed. + * + * If @invalidate is set, then the backing object will be invalidated and + * detached, otherwise it will just be detached. + */ +static inline +void fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate) +{ + if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) + __fscache_disable_cookie(cookie, invalidate); +} + +/** + * fscache_enable_cookie - Reenable a cookie + * @cookie: The cookie representing the cache object + * @can_enable: A function to permit enablement once lock is held + * @data: Data for can_enable() + * + * Reenable a previously disabled cookie, allowing it to accept further alloc, + * read, write, invalidate, update or acquire operations. An attempt will be + * made to immediately reattach the cookie to a backing object. + * + * The can_enable() function is called (if not NULL) once the enablement lock + * is held to rule on whether enablement is still permitted to go ahead. + */ +static inline +void fscache_enable_cookie(struct fscache_cookie *cookie, + bool (*can_enable)(void *data), + void *data) +{ + if (fscache_cookie_valid(cookie) && !fscache_cookie_enabled(cookie)) + __fscache_enable_cookie(cookie, can_enable, data); +} + #endif /* _LINUX_FSCACHE_H */ diff --git a/include/linux/fsl/mxs-dma.h b/include/linux/fsl/mxs-dma.h deleted file mode 100644 index 55d870238399..000000000000 --- a/include/linux/fsl/mxs-dma.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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 __MACH_MXS_DMA_H__ -#define __MACH_MXS_DMA_H__ - -#include <linux/dmaengine.h> - -struct mxs_dma_data { - int chan_irq; -}; - -extern int mxs_dma_is_apbh(struct dma_chan *chan); -extern int mxs_dma_is_apbx(struct dma_chan *chan); -#endif /* __MACH_MXS_DMA_H__ */ diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index a78680a92dba..1c804b057fb1 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -38,7 +38,7 @@ static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u3 static inline int fsnotify_perm(struct file *file, int mask) { struct path *path = &file->f_path; - struct inode *inode = path->dentry->d_inode; + struct inode *inode = file_inode(file); __u32 fsnotify_mask = 0; int ret; @@ -192,7 +192,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) static inline void fsnotify_access(struct file *file) { struct path *path = &file->f_path; - struct inode *inode = path->dentry->d_inode; + struct inode *inode = file_inode(file); __u32 mask = FS_ACCESS; if (S_ISDIR(inode->i_mode)) @@ -210,7 +210,7 @@ static inline void fsnotify_access(struct file *file) static inline void fsnotify_modify(struct file *file) { struct path *path = &file->f_path; - struct inode *inode = path->dentry->d_inode; + struct inode *inode = file_inode(file); __u32 mask = FS_MODIFY; if (S_ISDIR(inode->i_mode)) @@ -228,7 +228,7 @@ static inline void fsnotify_modify(struct file *file) static inline void fsnotify_open(struct file *file) { struct path *path = &file->f_path; - struct inode *inode = path->dentry->d_inode; + struct inode *inode = file_inode(file); __u32 mask = FS_OPEN; if (S_ISDIR(inode->i_mode)) diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index d5b0910d4961..4b2ee8d12f5e 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -157,7 +157,6 @@ struct fsnotify_group { struct inotify_group_private_data { spinlock_t idr_lock; struct idr idr; - u32 last_wd; struct user_struct *user; } inotify_data; #endif diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index e5ca8ef50e9b..9f15c0064c50 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -89,6 +89,9 @@ typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip, * that the call back has its own recursion protection. If it does * not set this, then the ftrace infrastructure will add recursion * protection for the caller. + * STUB - The ftrace_ops is just a place holder. + * INITIALIZED - The ftrace_ops has already been initialized (first use time + * register_ftrace_function() is called, it will initialized the ops) */ enum { FTRACE_OPS_FL_ENABLED = 1 << 0, @@ -98,6 +101,8 @@ enum { FTRACE_OPS_FL_SAVE_REGS = 1 << 4, FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED = 1 << 5, FTRACE_OPS_FL_RECURSION_SAFE = 1 << 6, + FTRACE_OPS_FL_STUB = 1 << 7, + FTRACE_OPS_FL_INITIALIZED = 1 << 8, }; struct ftrace_ops { @@ -108,6 +113,7 @@ struct ftrace_ops { #ifdef CONFIG_DYNAMIC_FTRACE struct ftrace_hash *notrace_hash; struct ftrace_hash *filter_hash; + struct mutex regex_lock; #endif }; @@ -259,8 +265,10 @@ struct ftrace_probe_ops { void (*func)(unsigned long ip, unsigned long parent_ip, void **data); - int (*callback)(unsigned long ip, void **data); - void (*free)(void **data); + int (*init)(struct ftrace_probe_ops *ops, + unsigned long ip, void **data); + void (*free)(struct ftrace_probe_ops *ops, + unsigned long ip, void **data); int (*print)(struct seq_file *m, unsigned long ip, struct ftrace_probe_ops *ops, @@ -394,7 +402,6 @@ ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos); ssize_t ftrace_notrace_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos); -loff_t ftrace_regex_lseek(struct file *file, loff_t offset, int whence); int ftrace_regex_release(struct inode *inode, struct file *file); void __init @@ -559,14 +566,12 @@ static inline ssize_t ftrace_filter_write(struct file *file, const char __user * size_t cnt, loff_t *ppos) { return -ENODEV; } static inline ssize_t ftrace_notrace_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos) { return -ENODEV; } -static inline loff_t ftrace_regex_lseek(struct file *file, loff_t offset, int whence) -{ - return -ENODEV; -} static inline int ftrace_regex_release(struct inode *inode, struct file *file) { return -ENODEV; } #endif /* CONFIG_DYNAMIC_FTRACE */ +loff_t ftrace_filter_lseek(struct file *file, loff_t offset, int whence); + /* totally disable ftrace - can not re-enable after this */ void ftrace_kill(void); @@ -819,10 +824,15 @@ enum ftrace_dump_mode; extern enum ftrace_dump_mode ftrace_dump_on_oops; +extern void disable_trace_on_warning(void); +extern int __disable_trace_on_warning; + #ifdef CONFIG_PREEMPT #define INIT_TRACE_RECURSION .trace_recursion = 0, #endif +#else /* CONFIG_TRACING */ +static inline void disable_trace_on_warning(void) { } #endif /* CONFIG_TRACING */ #ifndef INIT_TRACE_RECURSION diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 13a54d0bdfa8..5eaa746735ff 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -8,6 +8,7 @@ #include <linux/perf_event.h> struct trace_array; +struct trace_buffer; struct tracer; struct dentry; @@ -38,6 +39,12 @@ const char *ftrace_print_symbols_seq_u64(struct trace_seq *p, const char *ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int len); +struct trace_iterator; +struct trace_event; + +int ftrace_raw_output_prep(struct trace_iterator *iter, + struct trace_event *event); + /* * The trace entry - the most basic unit of tracing. This is what * is printed in the end as a single line in the trace output, such as: @@ -61,6 +68,7 @@ struct trace_entry { struct trace_iterator { struct trace_array *tr; struct tracer *trace; + struct trace_buffer *trace_buffer; void *private; int cpu_file; struct mutex mutex; @@ -70,6 +78,11 @@ struct trace_iterator { /* trace_seq for __print_flags() and __print_symbolic() etc. */ struct trace_seq tmp_seq; + cpumask_var_t started; + + /* it's true when current open file is snapshot */ + bool snapshot; + /* The below is zeroed out in pipe_read */ struct trace_seq seq; struct trace_entry *ent; @@ -82,10 +95,7 @@ struct trace_iterator { loff_t pos; long idx; - cpumask_var_t started; - - /* it's true when current open file is snapshot */ - bool snapshot; + /* All new field here will be zeroed out in pipe_read */ }; enum trace_iter_flags { @@ -95,8 +105,6 @@ enum trace_iter_flags { }; -struct trace_event; - typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter, int flags, struct trace_event *event); @@ -128,6 +136,13 @@ enum print_line_t { void tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, int pc); +struct ftrace_event_file; + +struct ring_buffer_event * +trace_event_buffer_lock_reserve(struct ring_buffer **current_buffer, + struct ftrace_event_file *ftrace_file, + int type, unsigned long len, + unsigned long flags, int pc); struct ring_buffer_event * trace_current_buffer_lock_reserve(struct ring_buffer **current_buffer, int type, unsigned long len, @@ -182,53 +197,49 @@ extern int ftrace_event_reg(struct ftrace_event_call *event, enum trace_reg type, void *data); enum { - TRACE_EVENT_FL_ENABLED_BIT, TRACE_EVENT_FL_FILTERED_BIT, - TRACE_EVENT_FL_RECORDED_CMD_BIT, TRACE_EVENT_FL_CAP_ANY_BIT, TRACE_EVENT_FL_NO_SET_FILTER_BIT, TRACE_EVENT_FL_IGNORE_ENABLE_BIT, + TRACE_EVENT_FL_WAS_ENABLED_BIT, }; +/* + * Event flags: + * FILTERED - The event has a filter attached + * CAP_ANY - Any user can enable for perf + * NO_SET_FILTER - Set when filter has error and is to be ignored + * IGNORE_ENABLE - For ftrace internal events, do not enable with debugfs file + * WAS_ENABLED - Set and stays set when an event was ever enabled + * (used for module unloading, if a module event is enabled, + * it is best to clear the buffers that used it). + */ enum { - TRACE_EVENT_FL_ENABLED = (1 << TRACE_EVENT_FL_ENABLED_BIT), TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), - TRACE_EVENT_FL_RECORDED_CMD = (1 << TRACE_EVENT_FL_RECORDED_CMD_BIT), TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT), TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT), TRACE_EVENT_FL_IGNORE_ENABLE = (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT), + TRACE_EVENT_FL_WAS_ENABLED = (1 << TRACE_EVENT_FL_WAS_ENABLED_BIT), }; struct ftrace_event_call { struct list_head list; struct ftrace_event_class *class; char *name; - struct dentry *dir; struct trace_event event; const char *print_fmt; struct event_filter *filter; + struct list_head *files; void *mod; void *data; - /* - * 32 bit flags: - * bit 1: enabled - * bit 2: filter_active - * bit 3: enabled cmd record - * bit 4: allow trace by non root (cap any) - * bit 5: failed to apply filter - * bit 6: ftrace internal event (do not enable) - * - * Changes to flags must hold the event_mutex. - * - * Note: Reads of flags do not hold the event_mutex since - * they occur in critical sections. But the way flags - * is currently used, these changes do no affect the code - * except that when a change is made, it may have a slight - * delay in propagating the changes to other CPUs due to - * caching and such. + * bit 0: filter_active + * bit 1: allow trace by non root (cap any) + * bit 2: failed to apply filter + * bit 3: ftrace internal event (do not enable) + * bit 4: Event was enabled by module */ - unsigned int flags; + int flags; /* static flags of different events */ #ifdef CONFIG_PERF_EVENTS int perf_refcount; @@ -236,6 +247,57 @@ struct ftrace_event_call { #endif }; +struct trace_array; +struct ftrace_subsystem_dir; + +enum { + FTRACE_EVENT_FL_ENABLED_BIT, + FTRACE_EVENT_FL_RECORDED_CMD_BIT, + FTRACE_EVENT_FL_SOFT_MODE_BIT, + FTRACE_EVENT_FL_SOFT_DISABLED_BIT, +}; + +/* + * Ftrace event file flags: + * ENABLED - The event is enabled + * RECORDED_CMD - The comms should be recorded at sched_switch + * SOFT_MODE - The event is enabled/disabled by SOFT_DISABLED + * SOFT_DISABLED - When set, do not trace the event (even though its + * tracepoint may be enabled) + */ +enum { + FTRACE_EVENT_FL_ENABLED = (1 << FTRACE_EVENT_FL_ENABLED_BIT), + FTRACE_EVENT_FL_RECORDED_CMD = (1 << FTRACE_EVENT_FL_RECORDED_CMD_BIT), + FTRACE_EVENT_FL_SOFT_MODE = (1 << FTRACE_EVENT_FL_SOFT_MODE_BIT), + FTRACE_EVENT_FL_SOFT_DISABLED = (1 << FTRACE_EVENT_FL_SOFT_DISABLED_BIT), +}; + +struct ftrace_event_file { + struct list_head list; + struct ftrace_event_call *event_call; + struct dentry *dir; + struct trace_array *tr; + struct ftrace_subsystem_dir *system; + + /* + * 32 bit flags: + * bit 0: enabled + * bit 1: enabled cmd record + * bit 2: enable/disable with the soft disable bit + * bit 3: soft disabled + * + * Note: The bits must be set atomically to prevent races + * from other writers. Reads of flags do not need to be in + * sync as they occur in critical sections. But the way flags + * is currently used, these changes do not affect the code + * except that when a change is made, it may have a slight + * delay in propagating the changes to other CPUs due to + * caching and such. Which is mostly OK ;-) + */ + unsigned long flags; + atomic_t sm_ref; /* soft-mode reference counter */ +}; + #define __TRACE_EVENT_FLAGS(name, value) \ static int __init trace_init_flags_##name(void) \ { \ @@ -272,9 +334,9 @@ extern int trace_define_field(struct ftrace_event_call *call, const char *type, const char *name, int offset, int size, int is_signed, int filter_type); extern int trace_add_event_call(struct ftrace_event_call *call); -extern void trace_remove_event_call(struct ftrace_event_call *call); +extern int trace_remove_event_call(struct ftrace_event_call *call); -#define is_signed_type(type) (((type)(-1)) < (type)0) +#define is_signed_type(type) (((type)(-1)) < (type)1) int trace_set_clr_event(const char *system, const char *event, int set); @@ -297,6 +359,40 @@ do { \ __trace_printk(ip, fmt, ##args); \ } while (0) +/** + * tracepoint_string - register constant persistent string to trace system + * @str - a constant persistent string that will be referenced in tracepoints + * + * If constant strings are being used in tracepoints, it is faster and + * more efficient to just save the pointer to the string and reference + * that with a printf "%s" instead of saving the string in the ring buffer + * and wasting space and time. + * + * The problem with the above approach is that userspace tools that read + * the binary output of the trace buffers do not have access to the string. + * Instead they just show the address of the string which is not very + * useful to users. + * + * With tracepoint_string(), the string will be registered to the tracing + * system and exported to userspace via the debugfs/tracing/printk_formats + * file that maps the string address to the string text. This way userspace + * tools that read the binary buffers have a way to map the pointers to + * the ASCII strings they represent. + * + * The @str used must be a constant string and persistent as it would not + * make sense to show a string that no longer exists. But it is still fine + * to be used with modules, because when modules are unloaded, if they + * had tracepoints, the ring buffers are cleared too. As long as the string + * does not change during the life of the module, it is fine to use + * tracepoint_string() within a module. + */ +#define tracepoint_string(str) \ + ({ \ + static const char *___tp_str __tracepoint_string = str; \ + ___tp_str; \ + }) +#define __tracepoint_string __attribute__((section("__tracepoint_str"))) + #ifdef CONFIG_PERF_EVENTS struct perf_event; diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index dd7c569aacad..f8d41cb1cbe0 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -29,6 +29,10 @@ #ifndef __GENALLOC_H__ #define __GENALLOC_H__ + +struct device; +struct device_node; + /** * Allocation callback function type definition * @map: Pointer to bitmap @@ -62,8 +66,8 @@ struct gen_pool_chunk { struct list_head next_chunk; /* next chunk in pool */ atomic_t avail; phys_addr_t phys_addr; /* physical starting address of memory chunk */ - unsigned long start_addr; /* starting address of memory chunk */ - unsigned long end_addr; /* ending address of memory chunk */ + unsigned long start_addr; /* start address of memory chunk */ + unsigned long end_addr; /* end address of memory chunk (inclusive) */ unsigned long bits[0]; /* bitmap for allocating memory chunk */ }; @@ -105,4 +109,18 @@ extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data); +extern struct gen_pool *devm_gen_pool_create(struct device *dev, + int min_alloc_order, int nid); +extern struct gen_pool *dev_get_gen_pool(struct device *dev); + +#ifdef CONFIG_OF +extern struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index); +#else +static inline struct gen_pool *of_get_named_gen_pool(struct device_node *np, + const char *propname, int index) +{ + return NULL; +} +#endif #endif /* __GENALLOC_H__ */ diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 0f615eb23d05..9b4dd491f7e8 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -209,7 +209,7 @@ static inline int allocflags_to_migratetype(gfp_t gfp_flags) * 0x9 => DMA or NORMAL (MOVABLE+DMA) * 0xa => MOVABLE (Movable is valid only if HIGHMEM is set too) * 0xb => BAD (MOVABLE+HIGHMEM+DMA) - * 0xc => DMA32 (MOVABLE+HIGHMEM+DMA32) + * 0xc => DMA32 (MOVABLE+DMA32) * 0xd => BAD (MOVABLE+DMA32+DMA) * 0xe => BAD (MOVABLE+DMA32+HIGHMEM) * 0xf => BAD (MOVABLE+DMA32+HIGHMEM+DMA) diff --git a/include/linux/gpio-pxa.h b/include/linux/gpio-pxa.h index d755b28ba635..d90ebbe02ca4 100644 --- a/include/linux/gpio-pxa.h +++ b/include/linux/gpio-pxa.h @@ -14,6 +14,7 @@ extern int pxa_last_gpio; extern int pxa_irq_to_gpio(int irq); struct pxa_gpio_platform_data { + int irq_base; int (*gpio_set_wake)(unsigned int gpio, unsigned int on); }; diff --git a/include/linux/gpio.h b/include/linux/gpio.h index f6c7ae3e223b..552e3f46e4a3 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -39,7 +39,7 @@ struct gpio { const char *label; }; -#ifdef CONFIG_GENERIC_GPIO +#ifdef CONFIG_GPIOLIB #ifdef CONFIG_ARCH_HAVE_CUSTOM_GPIO_H #include <asm/gpio.h> @@ -74,7 +74,7 @@ static inline int irq_to_gpio(unsigned int irq) #endif /* ! CONFIG_ARCH_HAVE_CUSTOM_GPIO_H */ -#else /* ! CONFIG_GENERIC_GPIO */ +#else /* ! CONFIG_GPIOLIB */ #include <linux/kernel.h> #include <linux/types.h> @@ -226,7 +226,7 @@ gpiochip_remove_pin_ranges(struct gpio_chip *chip) WARN_ON(1); } -#endif /* ! CONFIG_GENERIC_GPIO */ +#endif /* ! CONFIG_GPIOLIB */ struct device; diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 29eb805ea4a6..d9cf963ac832 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -1,136 +1,15 @@ #ifndef LINUX_HARDIRQ_H #define LINUX_HARDIRQ_H -#include <linux/preempt.h> +#include <linux/preempt_mask.h> #include <linux/lockdep.h> #include <linux/ftrace_irq.h> #include <linux/vtime.h> -#include <asm/hardirq.h> -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - * The hardirq count can in theory reach the same as NR_IRQS. - * In reality, the number of nested IRQS is limited to the stack - * size as well. For archs with over 1000 IRQS it is not practical - * to expect that they will all nest. We give a max of 10 bits for - * hardirq nesting. An arch may choose to give less than 10 bits. - * m68k expects it to be 8. - * - * - bits 16-25 are the hardirq count (max # of nested hardirqs: 1024) - * - bit 26 is the NMI_MASK - * - bit 27 is the PREEMPT_ACTIVE flag - * - * PREEMPT_MASK: 0x000000ff - * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x03ff0000 - * NMI_MASK: 0x04000000 - */ -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 -#define NMI_BITS 1 - -#define MAX_HARDIRQ_BITS 10 - -#ifndef HARDIRQ_BITS -# define HARDIRQ_BITS MAX_HARDIRQ_BITS -#endif - -#if HARDIRQ_BITS > MAX_HARDIRQ_BITS -#error HARDIRQ_BITS too high! -#endif - -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) -#define NMI_SHIFT (HARDIRQ_SHIFT + HARDIRQ_BITS) - -#define __IRQ_MASK(x) ((1UL << (x))-1) - -#define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) -#define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) -#define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) -#define NMI_MASK (__IRQ_MASK(NMI_BITS) << NMI_SHIFT) -#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) -#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) -#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) -#define NMI_OFFSET (1UL << NMI_SHIFT) - -#define SOFTIRQ_DISABLE_OFFSET (2 * SOFTIRQ_OFFSET) - -#ifndef PREEMPT_ACTIVE -#define PREEMPT_ACTIVE_BITS 1 -#define PREEMPT_ACTIVE_SHIFT (NMI_SHIFT + NMI_BITS) -#define PREEMPT_ACTIVE (__IRQ_MASK(PREEMPT_ACTIVE_BITS) << PREEMPT_ACTIVE_SHIFT) -#endif - -#if PREEMPT_ACTIVE < (1 << (NMI_SHIFT + NMI_BITS)) -#error PREEMPT_ACTIVE is too low! -#endif - -#define hardirq_count() (preempt_count() & HARDIRQ_MASK) -#define softirq_count() (preempt_count() & SOFTIRQ_MASK) -#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \ - | NMI_MASK)) - -/* - * Are we doing bottom half or hardware interrupt processing? - * Are we in a softirq context? Interrupt context? - * in_softirq - Are we currently processing softirq or have bh disabled? - * in_serving_softirq - Are we currently processing softirq? - */ -#define in_irq() (hardirq_count()) -#define in_softirq() (softirq_count()) -#define in_interrupt() (irq_count()) -#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET) - -/* - * Are we in NMI context? - */ -#define in_nmi() (preempt_count() & NMI_MASK) - -#if defined(CONFIG_PREEMPT_COUNT) -# define PREEMPT_CHECK_OFFSET 1 -#else -# define PREEMPT_CHECK_OFFSET 0 -#endif - -/* - * Are we running in atomic context? WARNING: this macro cannot - * always detect atomic context; in particular, it cannot know about - * held spinlocks in non-preemptible kernels. Thus it should not be - * used in the general case to determine whether sleeping is possible. - * Do not use in_atomic() in driver code. - */ -#define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != 0) - -/* - * Check whether we were atomic before we did preempt_disable(): - * (used by the scheduler, *after* releasing the kernel lock) - */ -#define in_atomic_preempt_off() \ - ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET) - -#ifdef CONFIG_PREEMPT_COUNT -# define preemptible() (preempt_count() == 0 && !irqs_disabled()) -# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) -#else -# define preemptible() 0 -# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET -#endif - -#if defined(CONFIG_SMP) || defined(CONFIG_GENERIC_HARDIRQS) extern void synchronize_irq(unsigned int irq); -#else -# define synchronize_irq(irq) barrier() -#endif -#if defined(CONFIG_TINY_RCU) || defined(CONFIG_TINY_PREEMPT_RCU) +#if defined(CONFIG_TINY_RCU) static inline void rcu_nmi_enter(void) { @@ -154,7 +33,7 @@ extern void rcu_nmi_exit(void); #define __irq_enter() \ do { \ account_irq_enter_time(current); \ - add_preempt_count(HARDIRQ_OFFSET); \ + preempt_count_add(HARDIRQ_OFFSET); \ trace_hardirq_enter(); \ } while (0) @@ -170,7 +49,7 @@ extern void irq_enter(void); do { \ trace_hardirq_exit(); \ account_irq_exit_time(current); \ - sub_preempt_count(HARDIRQ_OFFSET); \ + preempt_count_sub(HARDIRQ_OFFSET); \ } while (0) /* @@ -183,7 +62,7 @@ extern void irq_exit(void); lockdep_off(); \ ftrace_nmi_enter(); \ BUG_ON(in_nmi()); \ - add_preempt_count(NMI_OFFSET + HARDIRQ_OFFSET); \ + preempt_count_add(NMI_OFFSET + HARDIRQ_OFFSET); \ rcu_nmi_enter(); \ trace_hardirq_enter(); \ } while (0) @@ -193,7 +72,7 @@ extern void irq_exit(void); trace_hardirq_exit(); \ rcu_nmi_exit(); \ BUG_ON(!in_nmi()); \ - sub_preempt_count(NMI_OFFSET + HARDIRQ_OFFSET); \ + preempt_count_sub(NMI_OFFSET + HARDIRQ_OFFSET); \ ftrace_nmi_exit(); \ lockdep_on(); \ } while (0) diff --git a/include/linux/hash.h b/include/linux/hash.h index 61c97ae22e01..f09a0ae4d858 100644 --- a/include/linux/hash.h +++ b/include/linux/hash.h @@ -15,6 +15,7 @@ */ #include <asm/types.h> +#include <linux/compiler.h> /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */ #define GOLDEN_RATIO_PRIME_32 0x9e370001UL @@ -31,7 +32,7 @@ #error Wordsize not 32 or 64 #endif -static inline u64 hash_64(u64 val, unsigned int bits) +static __always_inline u64 hash_64(u64 val, unsigned int bits) { u64 hash = val; diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index 3b589440ecfe..9231be9e90a2 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -18,11 +18,21 @@ enum hdmi_infoframe_type { HDMI_INFOFRAME_TYPE_AUDIO = 0x84, }; +#define HDMI_IEEE_OUI 0x000c03 #define HDMI_INFOFRAME_HEADER_SIZE 4 #define HDMI_AVI_INFOFRAME_SIZE 13 #define HDMI_SPD_INFOFRAME_SIZE 25 #define HDMI_AUDIO_INFOFRAME_SIZE 10 +#define HDMI_INFOFRAME_SIZE(type) \ + (HDMI_INFOFRAME_HEADER_SIZE + HDMI_ ## type ## _INFOFRAME_SIZE) + +struct hdmi_any_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; +}; + enum hdmi_colorspace { HDMI_COLORSPACE_RGB, HDMI_COLORSPACE_YUV422, @@ -100,9 +110,6 @@ struct hdmi_avi_infoframe { unsigned char version; unsigned char length; enum hdmi_colorspace colorspace; - bool active_info_valid; - bool horizontal_bar_valid; - bool vertical_bar_valid; enum hdmi_scan_mode scan_mode; enum hdmi_colorimetry colorimetry; enum hdmi_picture_aspect picture_aspect; @@ -218,14 +225,52 @@ int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame); ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, void *buffer, size_t size); +enum hdmi_3d_structure { + HDMI_3D_STRUCTURE_INVALID = -1, + HDMI_3D_STRUCTURE_FRAME_PACKING = 0, + HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE, + HDMI_3D_STRUCTURE_LINE_ALTERNATIVE, + HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL, + HDMI_3D_STRUCTURE_L_DEPTH, + HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH, + HDMI_3D_STRUCTURE_TOP_AND_BOTTOM, + HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF = 8, +}; + + struct hdmi_vendor_infoframe { enum hdmi_infoframe_type type; unsigned char version; unsigned char length; - u8 data[27]; + unsigned int oui; + u8 vic; + enum hdmi_3d_structure s3d_struct; + unsigned int s3d_ext_data; }; +int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame); ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, void *buffer, size_t size); +union hdmi_vendor_any_infoframe { + struct { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; + unsigned int oui; + } any; + struct hdmi_vendor_infoframe hdmi; +}; + +union hdmi_infoframe { + struct hdmi_any_infoframe any; + struct hdmi_avi_infoframe avi; + struct hdmi_spd_infoframe spd; + union hdmi_vendor_any_infoframe vendor; + struct hdmi_audio_infoframe audio; +}; + +ssize_t +hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size); + #endif /* _DRM_HDMI_H */ diff --git a/include/linux/hid-debug.h b/include/linux/hid-debug.h index 53744fa1c8b7..8663f216c563 100644 --- a/include/linux/hid-debug.h +++ b/include/linux/hid-debug.h @@ -22,11 +22,12 @@ * */ -#define HID_DEBUG_BUFSIZE 512 - #ifdef CONFIG_DEBUG_FS +#define HID_DEBUG_BUFSIZE 512 + void hid_dump_input(struct hid_device *, struct hid_usage *, __s32); +void hid_dump_report(struct hid_device *, int , u8 *, int); void hid_dump_device(struct hid_device *, struct seq_file *); void hid_dump_field(struct hid_field *, int, struct seq_file *); char *hid_resolv_usage(unsigned, struct seq_file *); @@ -50,6 +51,7 @@ struct hid_debug_list { #else #define hid_dump_input(a,b,c) do { } while (0) +#define hid_dump_report(a,b,c,d) do { } while (0) #define hid_dump_device(a,b) do { } while (0) #define hid_dump_field(a,b,c) do { } while (0) #define hid_resolv_usage(a,b) do { } while (0) diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h index ecefb7311dd6..32ba45158d39 100644 --- a/include/linux/hid-sensor-hub.h +++ b/include/linux/hid-sensor-hub.h @@ -172,7 +172,7 @@ struct hid_sensor_common { struct hid_sensor_hub_attribute_info sensitivity; }; -/*Convert from hid unit expo to regular exponent*/ +/* Convert from hid unit expo to regular exponent */ static inline int hid_sensor_convert_exponent(int unit_expo) { if (unit_expo < 0x08) diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h index 6f24446e7669..4f945d3ed49f 100644 --- a/include/linux/hid-sensor-ids.h +++ b/include/linux/hid-sensor-ids.h @@ -37,7 +37,7 @@ #define HID_USAGE_SENSOR_ANGL_VELOCITY_Y_AXIS 0x200458 #define HID_USAGE_SENSOR_ANGL_VELOCITY_Z_AXIS 0x200459 -/*ORIENTATION: Compass 3D: (200083) */ +/* ORIENTATION: Compass 3D: (200083) */ #define HID_USAGE_SENSOR_COMPASS_3D 0x200083 #define HID_USAGE_SENSOR_ORIENT_MAGN_HEADING 0x200471 #define HID_USAGE_SENSOR_ORIENT_MAGN_HEADING_X 0x200472 diff --git a/include/linux/hid.h b/include/linux/hid.h index e14b465b1146..31b9d299ef6c 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -252,6 +252,8 @@ struct hid_item { #define HID_OUTPUT_REPORT 1 #define HID_FEATURE_REPORT 2 +#define HID_REPORT_TYPES 3 + /* * HID connect requests */ @@ -282,6 +284,8 @@ struct hid_item { #define HID_QUIRK_BADPAD 0x00000020 #define HID_QUIRK_MULTI_INPUT 0x00000040 #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 +#define HID_QUIRK_NO_EMPTY_INPUT 0x00000100 +#define HID_QUIRK_NO_INIT_INPUT_REPORTS 0x00000200 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 #define HID_QUIRK_NO_INIT_REPORTS 0x20000000 @@ -294,6 +298,7 @@ struct hid_item { #define HID_GROUP_GENERIC 0x0001 #define HID_GROUP_MULTITOUCH 0x0002 #define HID_GROUP_SENSOR_HUB 0x0003 +#define HID_GROUP_MULTITOUCH_WIN_8 0x0004 /* * This is the global environment of the parser. This information is @@ -392,14 +397,14 @@ struct hid_report { struct hid_device *device; /* associated device */ }; +#define HID_MAX_IDS 256 + struct hid_report_enum { unsigned numbered; struct list_head report_list; - struct hid_report *report_id_hash[256]; + struct hid_report *report_id_hash[HID_MAX_IDS]; }; -#define HID_REPORT_TYPES 3 - #define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */ #define HID_MAX_BUFFER_SIZE 4096 /* 4kb */ #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ @@ -455,8 +460,10 @@ struct hid_device { /* device report descriptor */ enum hid_type type; /* device type (mouse, kbd, ...) */ unsigned country; /* HID country */ struct hid_report_enum report_enum[HID_REPORT_TYPES]; + struct work_struct led_work; /* delayed LED worker */ - struct semaphore driver_lock; /* protects the current driver */ + struct semaphore driver_lock; /* protects the current driver, except during input */ + struct semaphore driver_input_lock; /* protects the current driver */ struct device dev; /* device */ struct hid_driver *driver; struct hid_ll_driver *ll_driver; @@ -477,6 +484,7 @@ struct hid_device { /* device report descriptor */ unsigned int status; /* see STAT flags above */ unsigned claimed; /* Claimed by hidinput, hiddev? */ unsigned quirks; /* Various quirks the device can pull on us */ + bool io_started; /* Protected by driver_lock. If IO has started */ struct list_head inputs; /* The list of inputs */ void *hiddev; /* The hiddev structure */ @@ -512,6 +520,7 @@ struct hid_device { /* device report descriptor */ struct dentry *debug_rdesc; struct dentry *debug_events; struct list_head debug_list; + spinlock_t debug_list_lock; wait_queue_head_t debug_wait; }; @@ -528,6 +537,8 @@ static inline void hid_set_drvdata(struct hid_device *hdev, void *data) #define HID_GLOBAL_STACK_SIZE 4 #define HID_COLLECTION_STACK_SIZE 4 +#define HID_SCAN_FLAG_MT_WIN_8 0x00000001 + struct hid_parser { struct hid_global global; struct hid_global global_stack[HID_GLOBAL_STACK_SIZE]; @@ -536,6 +547,7 @@ struct hid_parser { unsigned collection_stack[HID_COLLECTION_STACK_SIZE]; unsigned collection_stack_ptr; struct hid_device *device; + unsigned scan_flags; }; struct hid_class_descriptor { @@ -599,6 +611,10 @@ struct hid_usage_id { * @resume: invoked on resume if device was not reset (NULL means nop) * @reset_resume: invoked on resume if device was reset (NULL means nop) * + * probe should return -errno on error, or 0 on success. During probe, + * input will not be passed to raw_event unless hid_device_io_start is + * called. + * * raw_event and event should return 0 on no action performed, 1 when no * further processing should be done and negative on error * @@ -662,6 +678,9 @@ struct hid_driver { * @hidinput_input_event: event input event (e.g. ff or leds) * @parse: this method is called only once to parse the device data, * shouldn't allocate anything to not leak memory + * @request: send report request to device (e.g. feature report) + * @wait: wait for buffered io to complete (send/recv reports) + * @idle: send idle request to device */ struct hid_ll_driver { int (*start)(struct hid_device *hdev); @@ -676,6 +695,13 @@ struct hid_ll_driver { unsigned int code, int value); int (*parse)(struct hid_device *hdev); + + void (*request)(struct hid_device *hdev, + struct hid_report *report, int reqtype); + + int (*wait)(struct hid_device *hdev); + int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); + }; #define PM_HINT_FULLON 1<<5 @@ -726,9 +752,14 @@ struct hid_field *hidinput_get_led_field(struct hid_device *hid); unsigned int hidinput_count_leds(struct hid_device *hid); __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code); void hid_output_report(struct hid_report *report, __u8 *data); +u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags); struct hid_device *hid_allocate_device(void); struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); +struct hid_report *hid_validate_values(struct hid_device *hid, + unsigned int type, unsigned int id, + unsigned int field_index, + unsigned int report_counts); int hid_open_report(struct hid_device *device); int hid_check_keys_pressed(struct hid_device *hid); int hid_connect(struct hid_device *hid, unsigned int connect_mask); @@ -738,6 +769,44 @@ const struct hid_device_id *hid_match_id(struct hid_device *hdev, s32 hid_snto32(__u32 value, unsigned n); /** + * hid_device_io_start - enable HID input during probe, remove + * + * @hid - the device + * + * This should only be called during probe or remove and only be + * called by the thread calling probe or remove. It will allow + * incoming packets to be delivered to the driver. + */ +static inline void hid_device_io_start(struct hid_device *hid) { + if (hid->io_started) { + dev_warn(&hid->dev, "io already started"); + return; + } + hid->io_started = true; + up(&hid->driver_input_lock); +} + +/** + * hid_device_io_stop - disable HID input during probe, remove + * + * @hid - the device + * + * Should only be called after hid_device_io_start. It will prevent + * incoming packets from going to the driver for the duration of + * probe, remove. If called during probe, packets will still go to the + * driver after probe is complete. This function should only be called + * by the thread calling probe or remove. + */ +static inline void hid_device_io_stop(struct hid_device *hid) { + if (!hid->io_started) { + dev_warn(&hid->dev, "io already stopped"); + return; + } + hid->io_started = false; + down(&hid->driver_input_lock); +} + +/** * hid_map_usage - map usage input bits * * @hidinput: hidinput which we are interested in @@ -883,6 +952,49 @@ static inline int hid_hw_power(struct hid_device *hdev, int level) return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0; } + +/** + * hid_hw_request - send report request to device + * + * @hdev: hid device + * @report: report to send + * @reqtype: hid request type + */ +static inline void hid_hw_request(struct hid_device *hdev, + struct hid_report *report, int reqtype) +{ + if (hdev->ll_driver->request) + hdev->ll_driver->request(hdev, report, reqtype); +} + +/** + * hid_hw_idle - send idle request to device + * + * @hdev: hid device + * @report: report to control + * @idle: idle state + * @reqtype: hid request type + */ +static inline int hid_hw_idle(struct hid_device *hdev, int report, int idle, + int reqtype) +{ + if (hdev->ll_driver->idle) + return hdev->ll_driver->idle(hdev, report, idle, reqtype); + + return 0; +} + +/** + * hid_hw_wait - wait for buffered io to complete + * + * @hdev: hid device + */ +static inline void hid_hw_wait(struct hid_device *hdev) +{ + if (hdev->ll_driver->wait) + hdev->ll_driver->wait(hdev); +} + int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, int interrupt); @@ -890,7 +1002,6 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); int usbhid_quirks_init(char **quirks_param); void usbhid_quirks_exit(void); -void usbhid_set_leds(struct hid_device *hid); #ifdef CONFIG_HID_PID int hid_pidff_init(struct hid_device *hid); diff --git a/include/linux/hidraw.h b/include/linux/hidraw.h index 2451662c728a..ddf52612eed8 100644 --- a/include/linux/hidraw.h +++ b/include/linux/hidraw.h @@ -23,6 +23,7 @@ struct hidraw { wait_queue_head_t wait; struct hid_device *hid; struct device *dev; + spinlock_t list_lock; struct list_head list; }; diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index cc07d2777bbe..d19a5c2d2270 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -157,6 +157,7 @@ enum hrtimer_base_type { HRTIMER_BASE_MONOTONIC, HRTIMER_BASE_REALTIME, HRTIMER_BASE_BOOTTIME, + HRTIMER_BASE_TAI, HRTIMER_MAX_CLOCK_BASES, }; @@ -327,7 +328,9 @@ extern ktime_t ktime_get(void); extern ktime_t ktime_get_real(void); extern ktime_t ktime_get_boottime(void); extern ktime_t ktime_get_monotonic_offset(void); -extern ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot); +extern ktime_t ktime_get_clocktai(void); +extern ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot, + ktime_t *offs_tai); DECLARE_PER_CPU(struct tick_device, tick_cpu_device); diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index ee1c244a62a1..3935428c57cf 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -60,9 +60,9 @@ extern pmd_t *page_check_address_pmd(struct page *page, #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER) #ifdef CONFIG_TRANSPARENT_HUGEPAGE -#define HPAGE_PMD_SHIFT HPAGE_SHIFT -#define HPAGE_PMD_MASK HPAGE_MASK -#define HPAGE_PMD_SIZE HPAGE_SIZE +#define HPAGE_PMD_SHIFT PMD_SHIFT +#define HPAGE_PMD_SIZE ((1UL) << HPAGE_PMD_SHIFT) +#define HPAGE_PMD_MASK (~(HPAGE_PMD_SIZE - 1)) extern bool is_vma_temporary_stack(struct vm_area_struct *vma); @@ -96,10 +96,11 @@ extern int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, pmd_t *dst_pmd, pmd_t *src_pmd, struct vm_area_struct *vma, unsigned long addr, unsigned long end); -extern int handle_pte_fault(struct mm_struct *mm, - struct vm_area_struct *vma, unsigned long address, - pte_t *pte, pmd_t *pmd, unsigned int flags); -extern int split_huge_page(struct page *page); +extern int split_huge_page_to_list(struct page *page, struct list_head *list); +static inline int split_huge_page(struct page *page) +{ + return split_huge_page_to_list(page, NULL); +} extern void __split_huge_page_pmd(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd); #define split_huge_page_pmd(__vma, __address, __pmd) \ @@ -119,7 +120,7 @@ extern void __split_huge_page_pmd(struct vm_area_struct *vma, } while (0) extern void split_huge_page_pmd_mm(struct mm_struct *mm, unsigned long address, pmd_t *pmd); -#if HPAGE_PMD_ORDER > MAX_ORDER +#if HPAGE_PMD_ORDER >= MAX_ORDER #error "hugepages can't be allocated by the buddy allocator" #endif extern int hugepage_madvise(struct vm_area_struct *vma, @@ -186,6 +187,11 @@ extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vm #define transparent_hugepage_enabled(__vma) 0 #define transparent_hugepage_flags 0UL +static inline int +split_huge_page_to_list(struct page *page, struct list_head *list) +{ + return 0; +} static inline int split_huge_page(struct page *page) { return 0; diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 16e4e9a643fb..0393270466c3 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -55,9 +55,9 @@ void __unmap_hugepage_range_final(struct mmu_gather *tlb, void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, unsigned long start, unsigned long end, struct page *ref_page); -int hugetlb_prefault(struct address_space *, struct vm_area_struct *); void hugetlb_report_meminfo(struct seq_file *); int hugetlb_report_node_meminfo(int, char *); +void hugetlb_show_meminfo(void); unsigned long hugetlb_total_pages(void); int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, unsigned int flags); @@ -66,8 +66,15 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to, vm_flags_t vm_flags); void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed); int dequeue_hwpoisoned_huge_page(struct page *page); +bool isolate_huge_page(struct page *page, struct list_head *list); +void putback_active_hugepage(struct page *page); +bool is_hugepage_active(struct page *page); void copy_huge_page(struct page *dst, struct page *src); +#ifdef CONFIG_ARCH_WANT_HUGE_PMD_SHARE +pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud); +#endif + extern unsigned long hugepages_treat_as_movable; extern const unsigned long hugetlb_zero, hugetlb_infinity; extern int sysctl_hugetlb_shm_group; @@ -109,11 +116,13 @@ static inline unsigned long hugetlb_total_pages(void) #define follow_hugetlb_page(m,v,p,vs,a,b,i,w) ({ BUG(); 0; }) #define follow_huge_addr(mm, addr, write) ERR_PTR(-EINVAL) #define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; }) -#define hugetlb_prefault(mapping, vma) ({ BUG(); 0; }) static inline void hugetlb_report_meminfo(struct seq_file *m) { } #define hugetlb_report_node_meminfo(n, buf) 0 +static inline void hugetlb_show_meminfo(void) +{ +} #define follow_huge_pmd(mm, addr, pmd, write) NULL #define follow_huge_pud(mm, addr, pud, write) NULL #define prepare_hugepage_range(file, addr, len) (-EINVAL) @@ -128,6 +137,9 @@ static inline int dequeue_hwpoisoned_huge_page(struct page *page) return 0; } +#define isolate_huge_page(p, l) false +#define putback_active_hugepage(p) do {} while (0) +#define is_hugepage_active(x) false static inline void copy_huge_page(struct page *dst, struct page *src) { } @@ -185,8 +197,7 @@ static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) extern const struct file_operations hugetlbfs_file_operations; extern const struct vm_operations_struct hugetlb_vm_ops; -struct file *hugetlb_file_setup(const char *name, unsigned long addr, - size_t size, vm_flags_t acct, +struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct, struct user_struct **user, int creat_flags, int page_size_log); @@ -205,8 +216,8 @@ static inline int is_file_hugepages(struct file *file) #define is_file_hugepages(file) 0 static inline struct file * -hugetlb_file_setup(const char *name, unsigned long addr, size_t size, - vm_flags_t acctflag, struct user_struct **user, int creat_flags, +hugetlb_file_setup(const char *name, size_t size, vm_flags_t acctflag, + struct user_struct **user, int creat_flags, int page_size_log) { return ERR_PTR(-ENOSYS); @@ -256,6 +267,8 @@ struct huge_bootmem_page { }; struct page *alloc_huge_page_node(struct hstate *h, int nid); +struct page *alloc_huge_page_noerr(struct vm_area_struct *vma, + unsigned long addr, int avoid_reserve); /* arch callback */ int __init alloc_bootmem_huge_page(struct hstate *h); @@ -284,6 +297,13 @@ static inline struct hstate *hstate_file(struct file *f) return hstate_inode(file_inode(f)); } +static inline struct hstate *hstate_sizelog(int page_size_log) +{ + if (!page_size_log) + return &default_hstate; + return size_to_hstate(1 << page_size_log); +} + static inline struct hstate *hstate_vma(struct vm_area_struct *vma) { return hstate_file(vma->vm_file); @@ -348,11 +368,37 @@ static inline int hstate_index(struct hstate *h) return h - hstates; } -#else +pgoff_t __basepage_index(struct page *page); + +/* Return page->index in PAGE_SIZE units */ +static inline pgoff_t basepage_index(struct page *page) +{ + if (!PageCompound(page)) + return page->index; + + return __basepage_index(page); +} + +extern void dissolve_free_huge_pages(unsigned long start_pfn, + unsigned long end_pfn); +int pmd_huge_support(void); +/* + * Currently hugepage migration is enabled only for pmd-based hugepage. + * This function will be updated when hugepage migration is more widely + * supported. + */ +static inline int hugepage_migration_support(struct hstate *h) +{ + return pmd_huge_support() && (huge_page_shift(h) == PMD_SHIFT); +} + +#else /* CONFIG_HUGETLB_PAGE */ struct hstate {}; #define alloc_huge_page_node(h, nid) NULL +#define alloc_huge_page_noerr(v, a, r) NULL #define alloc_bootmem_huge_page(h) NULL #define hstate_file(f) NULL +#define hstate_sizelog(s) NULL #define hstate_vma(v) NULL #define hstate_inode(i) NULL #define huge_page_size(h) PAGE_SIZE @@ -367,6 +413,14 @@ static inline unsigned int pages_per_huge_page(struct hstate *h) } #define hstate_index_to_shift(index) 0 #define hstate_index(h) 0 -#endif + +static inline pgoff_t basepage_index(struct page *page) +{ + return page->index; +} +#define dissolve_free_huge_pages(s, e) do {} while (0) +#define pmd_huge_support() 0 +#define hugepage_migration_support(h) 0 +#endif /* CONFIG_HUGETLB_PAGE */ #endif /* _LINUX_HUGETLB_H */ diff --git a/include/linux/hwmon-vid.h b/include/linux/hwmon-vid.h index f346e4d5381c..da0a680e2f6d 100644 --- a/include/linux/hwmon-vid.h +++ b/include/linux/hwmon-vid.h @@ -38,7 +38,7 @@ static inline int vid_to_reg(int val, u8 vrm) return ((val >= 1100) && (val <= 1850) ? ((18499 - val * 10) / 25 + 5) / 10 : -1); default: - return -1; + return -EINVAL; } } diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h index b2514f70d591..09354f6c1d63 100644 --- a/include/linux/hwmon.h +++ b/include/linux/hwmon.h @@ -15,9 +15,19 @@ #define _HWMON_H_ struct device; +struct attribute_group; struct device *hwmon_device_register(struct device *dev); +struct device * +hwmon_device_register_with_groups(struct device *dev, const char *name, + void *drvdata, + const struct attribute_group **groups); +struct device * +devm_hwmon_device_register_with_groups(struct device *dev, const char *name, + void *drvdata, + const struct attribute_group **groups); void hwmon_device_unregister(struct device *dev); +void devm_hwmon_device_unregister(struct device *dev); #endif diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index df77ba9a8166..15da677478dd 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -28,6 +28,74 @@ #include <linux/types.h> /* + * Framework version for util services. + */ +#define UTIL_FW_MINOR 0 + +#define UTIL_WS2K8_FW_MAJOR 1 +#define UTIL_WS2K8_FW_VERSION (UTIL_WS2K8_FW_MAJOR << 16 | UTIL_FW_MINOR) + +#define UTIL_FW_MAJOR 3 +#define UTIL_FW_VERSION (UTIL_FW_MAJOR << 16 | UTIL_FW_MINOR) + + +/* + * Implementation of host controlled snapshot of the guest. + */ + +#define VSS_OP_REGISTER 128 + +enum hv_vss_op { + VSS_OP_CREATE = 0, + VSS_OP_DELETE, + VSS_OP_HOT_BACKUP, + VSS_OP_GET_DM_INFO, + VSS_OP_BU_COMPLETE, + /* + * Following operations are only supported with IC version >= 5.0 + */ + VSS_OP_FREEZE, /* Freeze the file systems in the VM */ + VSS_OP_THAW, /* Unfreeze the file systems */ + VSS_OP_AUTO_RECOVER, + VSS_OP_COUNT /* Number of operations, must be last */ +}; + + +/* + * Header for all VSS messages. + */ +struct hv_vss_hdr { + __u8 operation; + __u8 reserved[7]; +} __attribute__((packed)); + + +/* + * Flag values for the hv_vss_check_feature. Linux supports only + * one value. + */ +#define VSS_HBU_NO_AUTO_RECOVERY 0x00000005 + +struct hv_vss_check_feature { + __u32 flags; +} __attribute__((packed)); + +struct hv_vss_check_dm_info { + __u32 flags; +} __attribute__((packed)); + +struct hv_vss_msg { + union { + struct hv_vss_hdr vss_hdr; + int error; + }; + union { + struct hv_vss_check_feature vss_cf; + struct hv_vss_check_dm_info dm_info; + }; +} __attribute__((packed)); + +/* * An implementation of HyperV key value pair (KVP) functionality for Linux. * * @@ -364,15 +432,6 @@ struct hv_ring_buffer_info { u32 ring_data_startoffset; }; -struct hv_ring_buffer_debug_info { - u32 current_interrupt_mask; - u32 current_read_index; - u32 current_write_index; - u32 bytes_avail_toread; - u32 bytes_avail_towrite; -}; - - /* * * hv_get_ringbuffer_availbytes() @@ -398,27 +457,6 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi, *read = dsize - *write; } - -/* - * We use the same version numbering for all Hyper-V modules. - * - * Definition of versioning is as follows; - * - * Major Number Changes for these scenarios; - * 1. When a new version of Windows Hyper-V - * is released. - * 2. A Major change has occurred in the - * Linux IC's. - * (For example the merge for the first time - * into the kernel) Every time the Major Number - * changes, the Revision number is reset to 0. - * Minor Number Changes when new functionality is added - * to the Linux IC's that is not a bug fix. - * - * 3.1 - Added completed hv_utils driver. Shutdown/Heartbeat/Timesync - */ -#define HV_DRV_VERSION "3.1" - /* * VMBUS version is 32 bit entity broken up into * two 16 bit quantities: major_number. minor_number. @@ -852,23 +890,7 @@ enum vmbus_channel_state { CHANNEL_OFFER_STATE, CHANNEL_OPENING_STATE, CHANNEL_OPEN_STATE, -}; - -struct vmbus_channel_debug_info { - u32 relid; - enum vmbus_channel_state state; - uuid_le interfacetype; - uuid_le interface_instance; - u32 monitorid; - u32 servermonitor_pending; - u32 servermonitor_latency; - u32 servermonitor_connectionid; - u32 clientmonitor_pending; - u32 clientmonitor_latency; - u32 clientmonitor_connectionid; - - struct hv_ring_buffer_debug_info inbound; - struct hv_ring_buffer_debug_info outbound; + CHANNEL_OPENED_STATE, }; /* @@ -989,6 +1011,38 @@ struct vmbus_channel { * preserve the earlier behavior. */ u32 target_vp; + /* + * Support for sub-channels. For high performance devices, + * it will be useful to have multiple sub-channels to support + * a scalable communication infrastructure with the host. + * The support for sub-channels is implemented as an extention + * to the current infrastructure. + * The initial offer is considered the primary channel and this + * offer message will indicate if the host supports sub-channels. + * The guest is free to ask for sub-channels to be offerred and can + * open these sub-channels as a normal "primary" channel. However, + * all sub-channels will have the same type and instance guids as the + * primary channel. Requests sent on a given channel will result in a + * response on the same channel. + */ + + /* + * Sub-channel creation callback. This callback will be called in + * process context when a sub-channel offer is received from the host. + * The guest can open the sub-channel in the context of this callback. + */ + void (*sc_creation_callback)(struct vmbus_channel *new_sc); + + spinlock_t sc_lock; + /* + * All Sub-channels of a primary channel are linked here. + */ + struct list_head sc_list; + /* + * The primary channel this sub-channel belongs to. + * This will be NULL for the primary channel. + */ + struct vmbus_channel *primary_channel; }; static inline void set_channel_read_state(struct vmbus_channel *c, bool state) @@ -1000,6 +1054,34 @@ void vmbus_onmessage(void *context); int vmbus_request_offers(void); +/* + * APIs for managing sub-channels. + */ + +void vmbus_set_sc_create_callback(struct vmbus_channel *primary_channel, + void (*sc_cr_cb)(struct vmbus_channel *new_sc)); + +/* + * Retrieve the (sub) channel on which to send an outgoing request. + * When a primary channel has multiple sub-channels, we choose a + * channel whose VCPU binding is closest to the VCPU on which + * this call is being made. + */ +struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary); + +/* + * Check if sub-channels have already been offerred. This API will be useful + * when the driver is unloaded after establishing sub-channels. In this case, + * when the driver is re-loaded, the driver would have to check if the + * subchannels have already been established before attempting to request + * the creation of sub-channels. + * This function returns TRUE to indicate that subchannels have already been + * created. + * This function should be invoked after setting the callback function for + * sub-channel creation. + */ +bool vmbus_are_subchannels_present(struct vmbus_channel *primary); + /* The format must be the same as struct vmdata_gpa_direct */ struct vmbus_channel_packet_page_buffer { u16 type; @@ -1076,19 +1158,8 @@ extern int vmbus_recvpacket_raw(struct vmbus_channel *channel, u64 *requestid); -extern void vmbus_get_debug_info(struct vmbus_channel *channel, - struct vmbus_channel_debug_info *debug); - extern void vmbus_ontimer(unsigned long data); -struct hv_dev_port_info { - u32 int_mask; - u32 read_idx; - u32 write_idx; - u32 bytes_avail_toread; - u32 bytes_avail_towrite; -}; - /* Base driver object */ struct hv_driver { const char *name; @@ -1253,6 +1324,34 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver); } /* + * VSS (Backup/Restore) GUID + */ +#define HV_VSS_GUID \ + .guid = { \ + 0x29, 0x2e, 0xfa, 0x35, 0x23, 0xea, 0x36, 0x42, \ + 0x96, 0xae, 0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40 \ + } +/* + * Synthetic Video GUID + * {DA0A7802-E377-4aac-8E77-0558EB1073F8} + */ +#define HV_SYNTHVID_GUID \ + .guid = { \ + 0x02, 0x78, 0x0a, 0xda, 0x77, 0xe3, 0xac, 0x4a, \ + 0x8e, 0x77, 0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8 \ + } + +/* + * Synthetic FC GUID + * {2f9bcc4a-0069-4af3-b76b-6fd0be528cda} + */ +#define HV_SYNTHFC_GUID \ + .guid = { \ + 0x4A, 0xCC, 0x9B, 0x2F, 0x69, 0x00, 0xF3, 0x4A, \ + 0xB7, 0x6B, 0x6F, 0xD0, 0xBE, 0x52, 0x8C, 0xDA \ + } + +/* * Common header for Hyper-V ICs */ @@ -1348,7 +1447,7 @@ struct hyperv_service_callback { }; #define MAX_SRV_VER 0x7ffffff -extern void vmbus_prep_negotiate_resp(struct icmsg_hdr *, +extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *, struct icmsg_negotiate *, u8 *, int, int); @@ -1356,6 +1455,10 @@ int hv_kvp_init(struct hv_util_service *); void hv_kvp_deinit(void); void hv_kvp_onchannelcallback(void *); +int hv_vss_init(struct hv_util_service *); +void hv_vss_deinit(void); +void hv_vss_onchannelcallback(void *); + /* * Negotiated version with the Host. */ diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h index 40cb05a97b46..b5f9a007a3ab 100644 --- a/include/linux/i2c-mux.h +++ b/include/linux/i2c-mux.h @@ -42,7 +42,7 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, int (*deselect) (struct i2c_adapter *, void *mux_dev, u32 chan_id)); -int i2c_del_mux_adapter(struct i2c_adapter *adap); +void i2c_del_mux_adapter(struct i2c_adapter *adap); #endif /* __KERNEL__ */ diff --git a/include/linux/i2c-tegra.h b/include/linux/i2c-tegra.h deleted file mode 100644 index 9c85da49857a..000000000000 --- a/include/linux/i2c-tegra.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * drivers/i2c/busses/i2c-tegra.c - * - * Copyright (C) 2010 Google, Inc. - * Author: Colin Cross <ccross@android.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _LINUX_I2C_TEGRA_H -#define _LINUX_I2C_TEGRA_H - -struct tegra_i2c_platform_data { - unsigned long bus_clk_rate; -}; - -#endif /* _LINUX_I2C_TEGRA_H */ diff --git a/include/linux/i2c.h b/include/linux/i2c.h index d0c4db7b4872..2ab11dc38077 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -125,7 +125,6 @@ extern s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, * struct i2c_driver - represent an I2C device driver * @class: What kind of i2c device we instantiate (for detect) * @attach_adapter: Callback for bus addition (deprecated) - * @detach_adapter: Callback for bus removal (deprecated) * @probe: Callback for device binding * @remove: Callback for device unbinding * @shutdown: Callback for device shutdown @@ -162,12 +161,10 @@ extern s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, struct i2c_driver { unsigned int class; - /* Notifies the driver that a new bus has appeared or is about to be - * removed. You should avoid using this, it will be removed in a - * near future. + /* Notifies the driver that a new bus has appeared. You should avoid + * using this, it will be removed in a near future. */ int (*attach_adapter)(struct i2c_adapter *) __deprecated; - int (*detach_adapter)(struct i2c_adapter *) __deprecated; /* Standard driver model interfaces */ int (*probe)(struct i2c_client *, const struct i2c_device_id *); @@ -370,6 +367,45 @@ struct i2c_algorithm { u32 (*functionality) (struct i2c_adapter *); }; +/** + * struct i2c_bus_recovery_info - I2C bus recovery information + * @recover_bus: Recover routine. Either pass driver's recover_bus() routine, or + * i2c_generic_scl_recovery() or i2c_generic_gpio_recovery(). + * @get_scl: This gets current value of SCL line. Mandatory for generic SCL + * recovery. Used internally for generic GPIO recovery. + * @set_scl: This sets/clears SCL line. Mandatory for generic SCL recovery. Used + * internally for generic GPIO recovery. + * @get_sda: This gets current value of SDA line. Optional for generic SCL + * recovery. Used internally, if sda_gpio is a valid GPIO, for generic GPIO + * recovery. + * @prepare_recovery: This will be called before starting recovery. Platform may + * configure padmux here for SDA/SCL line or something else they want. + * @unprepare_recovery: This will be called after completing recovery. Platform + * may configure padmux here for SDA/SCL line or something else they want. + * @scl_gpio: gpio number of the SCL line. Only required for GPIO recovery. + * @sda_gpio: gpio number of the SDA line. Only required for GPIO recovery. + */ +struct i2c_bus_recovery_info { + int (*recover_bus)(struct i2c_adapter *); + + int (*get_scl)(struct i2c_adapter *); + void (*set_scl)(struct i2c_adapter *, int val); + int (*get_sda)(struct i2c_adapter *); + + void (*prepare_recovery)(struct i2c_bus_recovery_info *bri); + void (*unprepare_recovery)(struct i2c_bus_recovery_info *bri); + + /* gpio recovery */ + int scl_gpio; + int sda_gpio; +}; + +int i2c_recover_bus(struct i2c_adapter *adap); + +/* Generic recovery routines */ +int i2c_generic_gpio_recovery(struct i2c_adapter *adap); +int i2c_generic_scl_recovery(struct i2c_adapter *adap); + /* * i2c_adapter is the structure used to identify a physical i2c bus along * with the access algorithms necessary to access it. @@ -393,6 +429,8 @@ struct i2c_adapter { struct mutex userspace_clients_lock; struct list_head userspace_clients; + + struct i2c_bus_recovery_info *bus_recovery_info; }; #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) @@ -409,11 +447,13 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data) static inline struct i2c_adapter * i2c_parent_is_i2c_adapter(const struct i2c_adapter *adapter) { +#if IS_ENABLED(I2C_MUX) struct device *parent = adapter->dev.parent; if (parent != NULL && parent->type == &i2c_adapter_type) return to_i2c_adapter(parent); else +#endif return NULL; } @@ -450,7 +490,7 @@ void i2c_unlock_adapter(struct i2c_adapter *); */ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) extern int i2c_add_adapter(struct i2c_adapter *); -extern int i2c_del_adapter(struct i2c_adapter *); +extern void i2c_del_adapter(struct i2c_adapter *); extern int i2c_add_numbered_adapter(struct i2c_adapter *); extern int i2c_register_driver(struct module *, struct i2c_driver *); @@ -504,10 +544,24 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap) #endif /* I2C */ -#if IS_ENABLED(CONFIG_ACPI_I2C) -extern void acpi_i2c_register_devices(struct i2c_adapter *adap); +#if IS_ENABLED(CONFIG_OF) +/* must call put_device() when done with returned i2c_client device */ +extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); + +/* must call put_device() when done with returned i2c_adapter device */ +extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node); + #else -static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {} -#endif + +static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) +{ + return NULL; +} + +static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) +{ + return NULL; +} +#endif /* CONFIG_OF */ #endif /* _LINUX_I2C_H */ diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h index f027f7a63511..99e379b74398 100644 --- a/include/linux/i2c/atmel_mxt_ts.h +++ b/include/linux/i2c/atmel_mxt_ts.h @@ -15,6 +15,9 @@ #include <linux/types.h> +/* For key_map array */ +#define MXT_NUM_GPIO 4 + /* Orient */ #define MXT_NORMAL 0x0 #define MXT_DIAGONAL 0x1 @@ -39,6 +42,8 @@ struct mxt_platform_data { unsigned int voltage; unsigned char orient; unsigned long irqflags; + bool is_tp; + const unsigned int key_map[MXT_NUM_GPIO]; }; #endif /* __LINUX_ATMEL_MXT_TS_H */ diff --git a/include/linux/i2c/i2c-hid.h b/include/linux/i2c/i2c-hid.h index 60e411d764d4..7aa901d92058 100644 --- a/include/linux/i2c/i2c-hid.h +++ b/include/linux/i2c/i2c-hid.h @@ -19,7 +19,8 @@ * @hid_descriptor_address: i2c register where the HID descriptor is stored. * * Note that it is the responsibility of the platform driver (or the acpi 5.0 - * driver) to setup the irq related to the gpio in the struct i2c_board_info. + * driver, or the flattened device tree) to setup the irq related to the gpio in + * the struct i2c_board_info. * The platform driver should also setup the gpio according to the device: * * A typical example is the following: diff --git a/include/linux/i2c/pxa-i2c.h b/include/linux/i2c/pxa-i2c.h index 1a9f65e6ec0f..53aab243cbd8 100644 --- a/include/linux/i2c/pxa-i2c.h +++ b/include/linux/i2c/pxa-i2c.h @@ -67,6 +67,9 @@ struct i2c_pxa_platform_data { unsigned int class; unsigned int use_pio :1; unsigned int fast_mode :1; + unsigned int high_mode:1; + unsigned char master_code; + unsigned long rate; }; extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info); diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 488debbef895..81cbbdb96aae 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -658,7 +658,6 @@ struct twl4030_power_data { bool use_poweroff; /* Board is wired for TWL poweroff */ }; -extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts); extern int twl4030_remove_script(u8 flags); extern void twl4030_power_off(void); @@ -726,7 +725,7 @@ struct twl4030_platform_data { struct regulator_init_data *clk32kg; struct regulator_init_data *v1v8; struct regulator_init_data *v2v1; - /* TWL6025 LDO regulators */ + /* TWL6032 LDO regulators */ struct regulator_init_data *ldo1; struct regulator_init_data *ldo2; struct regulator_init_data *ldo3; @@ -736,7 +735,7 @@ struct twl4030_platform_data { struct regulator_init_data *ldo7; struct regulator_init_data *ldoln; struct regulator_init_data *ldousb; - /* TWL6025 DCDC regulators */ + /* TWL6032 DCDC regulators */ struct regulator_init_data *smps3; struct regulator_init_data *smps4; struct regulator_init_data *vio6025; @@ -753,7 +752,7 @@ struct twl_regulator_driver_data { #define TPS_SUBSET BIT(1) /* tps659[23]0 have fewer LDOs */ #define TWL5031 BIT(2) /* twl5031 has different registers */ #define TWL6030_CLASS BIT(3) /* TWL6030 class */ -#define TWL6025_SUBCLASS BIT(4) /* TWL6025 has changed registers */ +#define TWL6032_SUBCLASS BIT(4) /* TWL6032 has changed registers */ #define TWL4030_ALLOW_UNSUPPORTED BIT(5) /* Some voltages are possible * but not officially supported. * This flag is necessary to @@ -840,20 +839,20 @@ static inline int twl4030charger_usb_en(int enable) { return 0; } #define TWL6030_REG_CLK32KG 48 /* LDOs on 6025 have different names */ -#define TWL6025_REG_LDO2 49 -#define TWL6025_REG_LDO4 50 -#define TWL6025_REG_LDO3 51 -#define TWL6025_REG_LDO5 52 -#define TWL6025_REG_LDO1 53 -#define TWL6025_REG_LDO7 54 -#define TWL6025_REG_LDO6 55 -#define TWL6025_REG_LDOLN 56 -#define TWL6025_REG_LDOUSB 57 +#define TWL6032_REG_LDO2 49 +#define TWL6032_REG_LDO4 50 +#define TWL6032_REG_LDO3 51 +#define TWL6032_REG_LDO5 52 +#define TWL6032_REG_LDO1 53 +#define TWL6032_REG_LDO7 54 +#define TWL6032_REG_LDO6 55 +#define TWL6032_REG_LDOLN 56 +#define TWL6032_REG_LDOUSB 57 /* 6025 DCDC supplies */ -#define TWL6025_REG_SMPS3 58 -#define TWL6025_REG_SMPS4 59 -#define TWL6025_REG_VIO 60 +#define TWL6032_REG_SMPS3 58 +#define TWL6032_REG_SMPS4 59 +#define TWL6032_REG_VIO 60 #endif /* End of __TWL4030_H */ diff --git a/include/linux/i2c/twl4030-madc.h b/include/linux/i2c/twl4030-madc.h index 530e11ba0738..01f595107048 100644 --- a/include/linux/i2c/twl4030-madc.h +++ b/include/linux/i2c/twl4030-madc.h @@ -39,6 +39,7 @@ struct twl4030_madc_conversion_method { * @do_avgP: sample the input channel for 4 consecutive cycles * @method: RT, SW1, SW2 * @type: Polling or interrupt based method + * @raw: Return raw value, do not convert it */ struct twl4030_madc_request { @@ -48,6 +49,7 @@ struct twl4030_madc_request { u16 type; bool active; bool result_pending; + bool raw; int rbuf[TWL4030_MADC_MAX_CHANNELS]; void (*func_cb)(int len, int channels, int *buf); }; diff --git a/include/linux/i8042.h b/include/linux/i8042.h index a986ff588944..0f9bafa17a02 100644 --- a/include/linux/i8042.h +++ b/include/linux/i8042.h @@ -31,6 +31,30 @@ #define I8042_CMD_MUX_PFX 0x0090 #define I8042_CMD_MUX_SEND 0x1090 +/* + * Status register bits. + */ + +#define I8042_STR_PARITY 0x80 +#define I8042_STR_TIMEOUT 0x40 +#define I8042_STR_AUXDATA 0x20 +#define I8042_STR_KEYLOCK 0x10 +#define I8042_STR_CMDDAT 0x08 +#define I8042_STR_MUXERR 0x04 +#define I8042_STR_IBF 0x02 +#define I8042_STR_OBF 0x01 + +/* + * Control register bits. + */ + +#define I8042_CTR_KBDINT 0x01 +#define I8042_CTR_AUXINT 0x02 +#define I8042_CTR_IGNKEYLOCK 0x08 +#define I8042_CTR_KBDDIS 0x10 +#define I8042_CTR_AUXDIS 0x20 +#define I8042_CTR_XLATE 0x40 + struct serio; #if defined(CONFIG_SERIO_I8042) || defined(CONFIG_SERIO_I8042_MODULE) diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h index b4f6c29caced..630f45335c73 100644 --- a/include/linux/icmpv6.h +++ b/include/linux/icmpv6.h @@ -11,9 +11,21 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb) #include <linux/netdevice.h> -extern void icmpv6_send(struct sk_buff *skb, - u8 type, u8 code, - __u32 info); +#if IS_ENABLED(CONFIG_IPV6) +extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info); + +typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info); +extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn); +extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn); + +#else + +static inline void icmpv6_send(struct sk_buff *skb, + u8 type, u8 code, __u32 info) +{ + +} +#endif extern int icmpv6_init(void); extern int icmpv6_err_convert(u8 type, u8 code, diff --git a/include/linux/idr.h b/include/linux/idr.h index a6f38b5c34e4..871a213a8477 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -42,6 +42,7 @@ struct idr { struct idr_layer *id_free; int layers; /* only valid w/o concurrent changes */ int id_free_cnt; + int cur; /* current pos for cyclic allocation */ spinlock_t lock; }; @@ -73,10 +74,9 @@ struct idr { */ void *idr_find_slowpath(struct idr *idp, int id); -int idr_pre_get(struct idr *idp, gfp_t gfp_mask); -int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id); void idr_preload(gfp_t gfp_mask); int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask); +int idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask); int idr_for_each(struct idr *idp, int (*fn)(int id, void *p, void *data), void *data); void *idr_get_next(struct idr *idp, int *nextid); @@ -99,7 +99,7 @@ static inline void idr_preload_end(void) /** * idr_find - return pointer for given id - * @idp: idr handle + * @idr: idr handle * @id: lookup key * * Return the pointer given the id it has been registered with. A %NULL @@ -120,30 +120,68 @@ static inline void *idr_find(struct idr *idr, int id) } /** - * idr_get_new - allocate new idr entry + * idr_for_each_entry - iterate over an idr's elements of a given type + * @idp: idr handle + * @entry: the type * to use as cursor + * @id: id entry's key + * + * @entry and @id do not need to be initialized before the loop, and + * after normal terminatinon @entry is left with the value NULL. This + * is convenient for a "not found" value. + */ +#define idr_for_each_entry(idp, entry, id) \ + for (id = 0; ((entry) = idr_get_next(idp, &(id))) != NULL; ++id) + +/* + * Don't use the following functions. These exist only to suppress + * deprecated warnings on EXPORT_SYMBOL()s. + */ +int __idr_pre_get(struct idr *idp, gfp_t gfp_mask); +int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id); +void __idr_remove_all(struct idr *idp); + +/** + * idr_pre_get - reserve resources for idr allocation + * @idp: idr handle + * @gfp_mask: memory allocation flags + * + * Part of old alloc interface. This is going away. Use + * idr_preload[_end]() and idr_alloc() instead. + */ +static inline int __deprecated idr_pre_get(struct idr *idp, gfp_t gfp_mask) +{ + return __idr_pre_get(idp, gfp_mask); +} + +/** + * idr_get_new_above - allocate new idr entry above or equal to a start id * @idp: idr handle * @ptr: pointer you want associated with the id + * @starting_id: id to start search at * @id: pointer to the allocated handle * - * Simple wrapper around idr_get_new_above() w/ @starting_id of zero. + * Part of old alloc interface. This is going away. Use + * idr_preload[_end]() and idr_alloc() instead. */ -static inline int idr_get_new(struct idr *idp, void *ptr, int *id) +static inline int __deprecated idr_get_new_above(struct idr *idp, void *ptr, + int starting_id, int *id) { - return idr_get_new_above(idp, ptr, 0, id); + return __idr_get_new_above(idp, ptr, starting_id, id); } /** - * idr_for_each_entry - iterate over an idr's elements of a given type - * @idp: idr handle - * @entry: the type * to use as cursor - * @id: id entry's key + * idr_get_new - allocate new idr entry + * @idp: idr handle + * @ptr: pointer you want associated with the id + * @id: pointer to the allocated handle + * + * Part of old alloc interface. This is going away. Use + * idr_preload[_end]() and idr_alloc() instead. */ -#define idr_for_each_entry(idp, entry, id) \ - for (id = 0, entry = (typeof(entry))idr_get_next((idp), &(id)); \ - entry != NULL; \ - ++id, entry = (typeof(entry))idr_get_next((idp), &(id))) - -void __idr_remove_all(struct idr *idp); /* don't use */ +static inline int __deprecated idr_get_new(struct idr *idp, void *ptr, int *id) +{ + return __idr_get_new_above(idp, ptr, 0, id); +} /** * idr_remove_all - remove all ids from the given idr tree diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 7e24fe0cfbcd..a5b598a79bec 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -16,6 +16,7 @@ #define LINUX_IEEE80211_H #include <linux/types.h> +#include <linux/if_ether.h> #include <asm/byteorder.h> /* @@ -113,11 +114,40 @@ #define IEEE80211_CTL_EXT_SSW_FBACK 0x9000 #define IEEE80211_CTL_EXT_SSW_ACK 0xa000 + +#define IEEE80211_SN_MASK ((IEEE80211_SCTL_SEQ) >> 4) +#define IEEE80211_MAX_SN IEEE80211_SN_MASK +#define IEEE80211_SN_MODULO (IEEE80211_MAX_SN + 1) + +static inline int ieee80211_sn_less(u16 sn1, u16 sn2) +{ + return ((sn1 - sn2) & IEEE80211_SN_MASK) > (IEEE80211_SN_MODULO >> 1); +} + +static inline u16 ieee80211_sn_add(u16 sn1, u16 sn2) +{ + return (sn1 + sn2) & IEEE80211_SN_MASK; +} + +static inline u16 ieee80211_sn_inc(u16 sn) +{ + return ieee80211_sn_add(sn, 1); +} + +static inline u16 ieee80211_sn_sub(u16 sn1, u16 sn2) +{ + return (sn1 - sn2) & IEEE80211_SN_MASK; +} + +#define IEEE80211_SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) +#define IEEE80211_SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) + /* miscellaneous IEEE 802.11 constants */ #define IEEE80211_MAX_FRAG_THRESHOLD 2352 #define IEEE80211_MAX_RTS_THRESHOLD 2353 #define IEEE80211_MAX_AID 2007 #define IEEE80211_MAX_TIM_LEN 251 +#define IEEE80211_MAX_MESH_PEERINGS 63 /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section 6.2.1.1.2. @@ -180,31 +210,31 @@ struct ieee80211_hdr { __le16 frame_control; __le16 duration_id; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; __le16 seq_ctrl; - u8 addr4[6]; -} __packed; + u8 addr4[ETH_ALEN]; +} __packed __aligned(2); struct ieee80211_hdr_3addr { __le16 frame_control; __le16 duration_id; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; __le16 seq_ctrl; -} __packed; +} __packed __aligned(2); struct ieee80211_qos_hdr { __le16 frame_control; __le16 duration_id; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; __le16 seq_ctrl; __le16 qos_ctrl; -} __packed; +} __packed __aligned(2); /** * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set @@ -579,9 +609,9 @@ struct ieee80211s_hdr { u8 flags; u8 ttl; __le32 seqnum; - u8 eaddr1[6]; - u8 eaddr2[6]; -} __packed; + u8 eaddr1[ETH_ALEN]; + u8 eaddr2[ETH_ALEN]; +} __packed __aligned(2); /* Mesh flags */ #define MESH_FLAGS_AE_A4 0x1 @@ -645,6 +675,36 @@ struct ieee80211_channel_sw_ie { } __packed; /** + * struct ieee80211_ext_chansw_ie + * + * This structure represents the "Extended Channel Switch Announcement element" + */ +struct ieee80211_ext_chansw_ie { + u8 mode; + u8 new_operating_class; + u8 new_ch_num; + u8 count; +} __packed; + +/** + * struct ieee80211_sec_chan_offs_ie - secondary channel offset IE + * @sec_chan_offs: secondary channel offset, uses IEEE80211_HT_PARAM_CHA_SEC_* + * values here + * This structure represents the "Secondary Channel Offset element" + */ +struct ieee80211_sec_chan_offs_ie { + u8 sec_chan_offs; +} __packed; + +/** + * struct ieee80211_wide_bw_chansw_ie - wide bandwidth channel switch IE + */ +struct ieee80211_wide_bw_chansw_ie { + u8 new_channel_width; + u8 new_center_freq_seg0, new_center_freq_seg1; +} __packed; + +/** * struct ieee80211_tim * * This structure refers to "Traffic Indication Map information element" @@ -699,7 +759,7 @@ struct ieee80211_rann_ie { u8 rann_flags; u8 rann_hopcount; u8 rann_ttl; - u8 rann_addr[6]; + u8 rann_addr[ETH_ALEN]; __le32 rann_seq; __le32 rann_interval; __le32 rann_metric; @@ -743,9 +803,9 @@ enum ieee80211_vht_opmode_bits { struct ieee80211_mgmt { __le16 frame_control; __le16 duration; - u8 da[6]; - u8 sa[6]; - u8 bssid[6]; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; __le16 seq_ctrl; union { struct { @@ -774,7 +834,7 @@ struct ieee80211_mgmt { struct { __le16 capab_info; __le16 listen_interval; - u8 current_ap[6]; + u8 current_ap[ETH_ALEN]; /* followed by SSID and Supported rates */ u8 variable[0]; } __packed reassoc_req; @@ -812,12 +872,15 @@ struct ieee80211_mgmt { } __packed wme_action; struct{ u8 action_code; - u8 element_id; - u8 length; - struct ieee80211_channel_sw_ie sw_elem; + u8 variable[0]; } __packed chan_switch; struct{ u8 action_code; + struct ieee80211_ext_chansw_ie data; + u8 variable[0]; + } __packed ext_chan_switch; + struct{ + u8 action_code; u8 dialog_token; u8 element_id; u8 length; @@ -875,7 +938,7 @@ struct ieee80211_mgmt { } u; } __packed action; } u; -} __packed; +} __packed __aligned(2); /* Supported Rates value encodings in 802.11n-2009 7.3.2.2 */ #define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 @@ -904,22 +967,22 @@ struct ieee80211_vendor_ie { struct ieee80211_rts { __le16 frame_control; __le16 duration; - u8 ra[6]; - u8 ta[6]; -} __packed; + u8 ra[ETH_ALEN]; + u8 ta[ETH_ALEN]; +} __packed __aligned(2); struct ieee80211_cts { __le16 frame_control; __le16 duration; - u8 ra[6]; -} __packed; + u8 ra[ETH_ALEN]; +} __packed __aligned(2); struct ieee80211_pspoll { __le16 frame_control; __le16 aid; - u8 bssid[6]; - u8 ta[6]; -} __packed; + u8 bssid[ETH_ALEN]; + u8 ta[ETH_ALEN]; +} __packed __aligned(2); /* TDLS */ @@ -927,14 +990,14 @@ struct ieee80211_pspoll { struct ieee80211_tdls_lnkie { u8 ie_type; /* Link Identifier IE */ u8 ie_len; - u8 bssid[6]; - u8 init_sta[6]; - u8 resp_sta[6]; + u8 bssid[ETH_ALEN]; + u8 init_sta[ETH_ALEN]; + u8 resp_sta[ETH_ALEN]; } __packed; struct ieee80211_tdls_data { - u8 da[6]; - u8 sa[6]; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; __be16 ether_type; u8 payload_type; u8 category; @@ -999,6 +1062,26 @@ enum ieee80211_p2p_attr_id { IEEE80211_P2P_ATTR_MAX }; +/* Notice of Absence attribute - described in P2P spec 4.1.14 */ +/* Typical max value used here */ +#define IEEE80211_P2P_NOA_DESC_MAX 4 + +struct ieee80211_p2p_noa_desc { + u8 count; + __le32 duration; + __le32 interval; + __le32 start_time; +} __packed; + +struct ieee80211_p2p_noa_attr { + u8 index; + u8 oppps_ctwindow; + struct ieee80211_p2p_noa_desc desc[IEEE80211_P2P_NOA_DESC_MAX]; +} __packed; + +#define IEEE80211_P2P_OPPPS_ENABLE_BIT BIT(7) +#define IEEE80211_P2P_OPPPS_CTWINDOW_MASK 0x7F + /** * struct ieee80211_bar - HT Block Ack Request * @@ -1008,8 +1091,8 @@ enum ieee80211_p2p_attr_id { struct ieee80211_bar { __le16 frame_control; __le16 duration; - __u8 ra[6]; - __u8 ta[6]; + __u8 ra[ETH_ALEN]; + __u8 ta[ETH_ALEN]; __le16 control; __le16 start_seq_num; } __packed; @@ -1290,11 +1373,6 @@ struct ieee80211_vht_operation { } __packed; -#define IEEE80211_VHT_MCS_ZERO_TO_SEVEN_SUPPORT 0 -#define IEEE80211_VHT_MCS_ZERO_TO_EIGHT_SUPPORT 1 -#define IEEE80211_VHT_MCS_ZERO_TO_NINE_SUPPORT 2 -#define IEEE80211_VHT_MCS_NOT_SUPPORTED 3 - /* 802.11ac VHT Capabilities */ #define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x00000000 #define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 0x00000001 @@ -1310,10 +1388,11 @@ struct ieee80211_vht_operation { #define IEEE80211_VHT_CAP_RXSTBC_2 0x00000200 #define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300 #define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400 +#define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700 #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 #define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000 -#define IEEE80211_VHT_CAP_SOUNDING_DIMENTION_MAX 0x00030000 +#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX 0x00030000 #define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000 #define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000 #define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000 @@ -1594,6 +1673,7 @@ enum ieee80211_eid { WLAN_EID_HT_CAPABILITY = 45, WLAN_EID_HT_OPERATION = 61, + WLAN_EID_SECONDARY_CHANNEL_OFFSET = 62, WLAN_EID_RSN = 48, WLAN_EID_MMIE = 76, @@ -1628,6 +1708,12 @@ enum ieee80211_eid { WLAN_EID_VHT_CAPABILITY = 191, WLAN_EID_VHT_OPERATION = 192, WLAN_EID_OPMODE_NOTIF = 199, + WLAN_EID_WIDE_BW_CHANNEL_SWITCH = 194, + WLAN_EID_CHANNEL_SWITCH_WRAPPER = 196, + WLAN_EID_EXTENDED_BSS_LOAD = 193, + WLAN_EID_VHT_TX_POWER_ENVELOPE = 195, + WLAN_EID_AID = 197, + WLAN_EID_QUIET_CHANNEL = 198, /* 802.11ad */ WLAN_EID_NON_TX_BSSID_CAP = 83, @@ -1749,8 +1835,18 @@ enum ieee80211_key_len { WLAN_KEY_LEN_AES_CMAC = 16, }; +#define IEEE80211_WEP_IV_LEN 4 +#define IEEE80211_WEP_ICV_LEN 4 +#define IEEE80211_CCMP_HDR_LEN 8 +#define IEEE80211_CCMP_MIC_LEN 8 +#define IEEE80211_CCMP_PN_LEN 6 +#define IEEE80211_TKIP_IV_LEN 8 +#define IEEE80211_TKIP_ICV_LEN 4 +#define IEEE80211_CMAC_PN_LEN 6 + /* Public action codes */ enum ieee80211_pub_actioncode { + WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4, WLAN_PUB_ACTION_TDLS_DISCOVER_RES = 14, }; @@ -1769,6 +1865,11 @@ enum ieee80211_tdls_actioncode { WLAN_TDLS_DISCOVERY_REQUEST = 10, }; +/* Interworking capabilities are set in 7th bit of 4th byte of the + * @WLAN_EID_EXT_CAPABILITY information element + */ +#define WLAN_EXT_CAPA4_INTERWORKING_ENABLED BIT(7) + /* * TDLS capabililites to be enabled in the 5th byte of the * @WLAN_EID_EXT_CAPABILITY information element @@ -1911,6 +2012,16 @@ enum ieee80211_timeout_interval_type { WLAN_TIMEOUT_ASSOC_COMEBACK = 3 /* 802.11w */, }; +/** + * struct ieee80211_timeout_interval_ie - Timeout Interval element + * @type: type, see &enum ieee80211_timeout_interval_type + * @value: timeout interval value + */ +struct ieee80211_timeout_interval_ie { + u8 type; + __le32 value; +} __packed; + /* BACK action code */ enum ieee80211_back_actioncode { WLAN_ACTION_ADDBA_REQ = 0, @@ -2178,4 +2289,8 @@ static inline bool ieee80211_check_tim(const struct ieee80211_tim_ie *tim, return !!(tim->virtual_map[index] & mask); } +/* convert time units */ +#define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) +#define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) + #endif /* LINUX_IEEE80211_H */ diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index 89b4614a4722..f563907ed776 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h @@ -33,7 +33,15 @@ static inline struct arphdr *arp_hdr(const struct sk_buff *skb) static inline int arp_hdr_len(struct net_device *dev) { - /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ - return sizeof(struct arphdr) + (dev->addr_len + sizeof(u32)) * 2; + switch (dev->type) { +#if IS_ENABLED(CONFIG_FIREWIRE_NET) + case ARPHRD_IEEE1394: + /* ARP header, device address and 2 IP addresses */ + return sizeof(struct arphdr) + dev->addr_len + sizeof(u32) * 2; +#endif + default: + /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ + return sizeof(struct arphdr) + (dev->addr_len + sizeof(u32)) * 2; + } } #endif /* _LINUX_IF_ARP_H */ diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 12b4d55a02af..d5569734f672 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -30,7 +30,6 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr); -int mac_pton(const char *s, u8 *mac); extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); #endif /* _LINUX_IF_ETHER_H */ diff --git a/include/linux/if_link.h b/include/linux/if_link.h index c3f817c3eb45..a86784dec3d3 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -12,5 +12,6 @@ struct ifla_vf_info { __u32 qos; __u32 tx_rate; __u32 spoofchk; + __u32 linkstate; }; #endif /* _LINUX_IF_LINK_H */ diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h index 84dde1dd1da4..ddd33fd5904d 100644 --- a/include/linux/if_macvlan.h +++ b/include/linux/if_macvlan.h @@ -8,7 +8,7 @@ #include <net/netlink.h> #include <linux/u64_stats_sync.h> -#if defined(CONFIG_MACVTAP) || defined(CONFIG_MACVTAP_MODULE) +#if IS_ENABLED(CONFIG_MACVTAP) struct socket *macvtap_get_socket(struct file *); #else #include <linux/err.h> @@ -50,7 +50,7 @@ struct macvlan_pcpu_stats { * Maximum times a macvtap device can be opened. This can be used to * configure the number of receive queue, e.g. for multiqueue virtio. */ -#define MAX_MACVTAP_QUEUES (NR_CPUS < 16 ? NR_CPUS : 16) +#define MAX_MACVTAP_QUEUES 16 #define MACVLAN_MC_FILTER_BITS 8 #define MACVLAN_MC_FILTER_SZ (1 << MACVLAN_MC_FILTER_BITS) @@ -65,12 +65,18 @@ struct macvlan_dev { DECLARE_BITMAP(mc_filter, MACVLAN_MC_FILTER_SZ); + netdev_features_t set_features; enum macvlan_mode mode; u16 flags; int (*receive)(struct sk_buff *skb); int (*forward)(struct net_device *dev, struct sk_buff *skb); - struct macvtap_queue *taps[MAX_MACVTAP_QUEUES]; + /* This array tracks active taps. */ + struct macvtap_queue __rcu *taps[MAX_MACVTAP_QUEUES]; + /* This list tracks all taps (both enabled and disabled) */ + struct list_head queue_list; int numvtaps; + int numqueues; + netdev_features_t tap_features; int minor; }; diff --git a/include/linux/if_team.h b/include/linux/if_team.h index cfd21e3d5506..a899dc24be15 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -10,9 +10,9 @@ #ifndef _LINUX_IF_TEAM_H_ #define _LINUX_IF_TEAM_H_ - #include <linux/netpoll.h> #include <net/sch_generic.h> +#include <linux/types.h> #include <uapi/linux/if_team.h> struct team_pcpu_stats { @@ -69,6 +69,7 @@ struct team_port { s32 priority; /* lower number ~ higher priority */ u16 queue_id; struct list_head qom_list; /* node in queue override mapping list */ + struct rcu_head rcu; long mode_priv[0]; }; @@ -112,6 +113,10 @@ struct team_mode_ops { void (*port_disabled)(struct team *team, struct team_port *port); }; +extern int team_modeop_port_enter(struct team *team, struct team_port *port); +extern void team_modeop_port_change_dev_addr(struct team *team, + struct team_port *port); + enum team_option_type { TEAM_OPTION_TYPE_U32, TEAM_OPTION_TYPE_STRING, @@ -189,6 +194,18 @@ struct team { bool user_carrier_enabled; bool queue_override_enabled; struct list_head *qom_lists; /* array of queue override mapping lists */ + struct { + unsigned int count; + unsigned int interval; /* in ms */ + atomic_t count_pending; + struct delayed_work dw; + } notify_peers; + struct { + unsigned int count; + unsigned int interval; /* in ms */ + atomic_t count_pending; + struct delayed_work dw; + } mcast_rejoin; long mode_priv[TEAM_MODE_PRIV_LONGS]; }; @@ -224,6 +241,16 @@ static inline struct team_port *team_get_port_by_index(struct team *team, return port; return NULL; } + +static inline int team_num_to_port_index(struct team *team, int num) +{ + int en_port_count = ACCESS_ONCE(team->en_port_count); + + if (unlikely(!en_port_count)) + return 0; + return num % en_port_count; +} + static inline struct team_port *team_get_port_by_index_rcu(struct team *team, int port_index) { @@ -236,7 +263,26 @@ static inline struct team_port *team_get_port_by_index_rcu(struct team *team, return NULL; } -extern int team_port_set_team_dev_addr(struct team_port *port); +static inline struct team_port * +team_get_first_port_txable_rcu(struct team *team, struct team_port *port) +{ + struct team_port *cur; + + if (likely(team_port_txable(port))) + return port; + cur = port; + list_for_each_entry_continue_rcu(cur, &team->port_list, list) + if (team_port_txable(cur)) + return cur; + list_for_each_entry_rcu(cur, &team->port_list, list) { + if (cur == port) + break; + if (team_port_txable(cur)) + return cur; + } + return NULL; +} + extern int team_options_register(struct team *team, const struct team_option *option, size_t option_count); diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 218a3b686d90..715c343f7c00 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -44,7 +44,7 @@ struct vlan_hdr { * struct vlan_ethhdr - vlan ethernet header (ethhdr + vlan_hdr) * @h_dest: destination ethernet address * @h_source: source ethernet address - * @h_vlan_proto: ethernet protocol (always 0x8100) + * @h_vlan_proto: ethernet protocol * @h_vlan_TCI: priority and VLAN ID * @h_vlan_encapsulated_proto: packet type ID or len */ @@ -79,22 +79,21 @@ static inline int is_vlan_dev(struct net_device *dev) } #define vlan_tx_tag_present(__skb) ((__skb)->vlan_tci & VLAN_TAG_PRESENT) -#define vlan_tx_nonzero_tag_present(__skb) \ - (vlan_tx_tag_present(__skb) && ((__skb)->vlan_tci & VLAN_VID_MASK)) #define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT) +#define vlan_tx_tag_get_id(__skb) ((__skb)->vlan_tci & VLAN_VID_MASK) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) extern struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, - u16 vlan_id); + __be16 vlan_proto, u16 vlan_id); extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); extern u16 vlan_dev_vlan_id(const struct net_device *dev); extern bool vlan_do_receive(struct sk_buff **skb); extern struct sk_buff *vlan_untag(struct sk_buff *skb); -extern int vlan_vid_add(struct net_device *dev, unsigned short vid); -extern void vlan_vid_del(struct net_device *dev, unsigned short vid); +extern int vlan_vid_add(struct net_device *dev, __be16 proto, u16 vid); +extern void vlan_vid_del(struct net_device *dev, __be16 proto, u16 vid); extern int vlan_vids_add_by_dev(struct net_device *dev, const struct net_device *by_dev); @@ -104,7 +103,8 @@ extern void vlan_vids_del_by_dev(struct net_device *dev, extern bool vlan_uses_dev(const struct net_device *dev); #else static inline struct net_device * -__vlan_find_dev_deep(struct net_device *real_dev, u16 vlan_id) +__vlan_find_dev_deep(struct net_device *real_dev, + __be16 vlan_proto, u16 vlan_id) { return NULL; } @@ -131,12 +131,12 @@ static inline struct sk_buff *vlan_untag(struct sk_buff *skb) return skb; } -static inline int vlan_vid_add(struct net_device *dev, unsigned short vid) +static inline int vlan_vid_add(struct net_device *dev, __be16 proto, u16 vid) { return 0; } -static inline void vlan_vid_del(struct net_device *dev, unsigned short vid) +static inline void vlan_vid_del(struct net_device *dev, __be16 proto, u16 vid) { } @@ -157,9 +157,20 @@ static inline bool vlan_uses_dev(const struct net_device *dev) } #endif +static inline bool vlan_hw_offload_capable(netdev_features_t features, + __be16 proto) +{ + if (proto == htons(ETH_P_8021Q) && features & NETIF_F_HW_VLAN_CTAG_TX) + return true; + if (proto == htons(ETH_P_8021AD) && features & NETIF_F_HW_VLAN_STAG_TX) + return true; + return false; +} + /** * vlan_insert_tag - regular VLAN tag inserting * @skb: skbuff to tag + * @vlan_proto: VLAN encapsulation protocol * @vlan_tci: VLAN TCI to insert * * Inserts the VLAN tag into @skb as part of the payload @@ -170,7 +181,8 @@ static inline bool vlan_uses_dev(const struct net_device *dev) * * Does not change skb->protocol so this function can be used during receive. */ -static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci) +static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, + __be16 vlan_proto, u16 vlan_tci) { struct vlan_ethhdr *veth; @@ -185,7 +197,7 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci) skb->mac_header -= VLAN_HLEN; /* first, the ethernet type */ - veth->h_vlan_proto = htons(ETH_P_8021Q); + veth->h_vlan_proto = vlan_proto; /* now, the TCI */ veth->h_vlan_TCI = htons(vlan_tci); @@ -204,30 +216,32 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, u16 vlan_tci) * Following the skb_unshare() example, in case of error, the calling function * doesn't have to worry about freeing the original skb. */ -static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci) +static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, + __be16 vlan_proto, u16 vlan_tci) { - skb = vlan_insert_tag(skb, vlan_tci); + skb = vlan_insert_tag(skb, vlan_proto, vlan_tci); if (skb) - skb->protocol = htons(ETH_P_8021Q); + skb->protocol = vlan_proto; return skb; } /** * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting * @skb: skbuff to tag + * @vlan_proto: VLAN encapsulation protocol * @vlan_tci: VLAN TCI to insert * * Puts the VLAN TCI in @skb->vlan_tci and lets the device do the rest */ static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb, + __be16 vlan_proto, u16 vlan_tci) { + skb->vlan_proto = vlan_proto; skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci; return skb; } -#define HAVE_VLAN_PUT_TAG - /** * vlan_put_tag - inserts VLAN tag according to device features * @skb: skbuff to tag @@ -236,12 +250,13 @@ static inline struct sk_buff *__vlan_hwaccel_put_tag(struct sk_buff *skb, * Assumes skb->dev is the target that will xmit this frame. * Returns a VLAN tagged skb. */ -static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, u16 vlan_tci) +static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, + __be16 vlan_proto, u16 vlan_tci) { - if (skb->dev->features & NETIF_F_HW_VLAN_TX) { - return __vlan_hwaccel_put_tag(skb, vlan_tci); + if (vlan_hw_offload_capable(skb->dev->features, vlan_proto)) { + return __vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci); } else { - return __vlan_put_tag(skb, vlan_tci); + return __vlan_put_tag(skb, vlan_proto, vlan_tci); } } @@ -256,9 +271,9 @@ static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) { struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data; - if (veth->h_vlan_proto != htons(ETH_P_8021Q)) { + if (veth->h_vlan_proto != htons(ETH_P_8021Q) && + veth->h_vlan_proto != htons(ETH_P_8021AD)) return -EINVAL; - } *vlan_tci = ntohs(veth->h_vlan_TCI); return 0; @@ -294,7 +309,7 @@ static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb, */ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) { - if (skb->dev->features & NETIF_F_HW_VLAN_TX) { + if (skb->dev->features & NETIF_F_HW_VLAN_CTAG_TX) { return __vlan_hwaccel_get_tag(skb, vlan_tci); } else { return __vlan_get_tag(skb, vlan_tci); @@ -339,7 +354,7 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb, */ proto = vhdr->h_vlan_encapsulated_proto; - if (ntohs(proto) >= 1536) { + if (ntohs(proto) >= ETH_P_802_3_MIN) { skb->protocol = proto; return; } diff --git a/include/linux/igmp.h b/include/linux/igmp.h index 7f2bf1518480..f47550d75f85 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -84,6 +84,7 @@ struct ip_mc_list { struct ip_mc_list *next; struct ip_mc_list __rcu *next_rcu; }; + struct ip_mc_list __rcu *next_hash; struct timer_list timer; int users; atomic_t refcnt; @@ -128,6 +129,5 @@ extern void ip_mc_unmap(struct in_device *); extern void ip_mc_remap(struct in_device *); extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr); extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr); -extern void ip_mc_rejoin_groups(struct in_device *in_dev); #endif diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h index 2e4eab9868a3..e7fdec4db9da 100644 --- a/include/linux/iio/adc/ad_sigma_delta.h +++ b/include/linux/iio/adc/ad_sigma_delta.h @@ -133,9 +133,9 @@ int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig); .channel2 = (_channel2), \ .address = (_address), \ .extend_name = (_extend_name), \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .scan_index = (_si), \ .scan_type = { \ .sign = 'u', \ diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 2bac0eb8948d..a1124bdc4cac 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -36,7 +36,7 @@ struct iio_buffer; * any of them not existing. **/ struct iio_buffer_access_funcs { - int (*store_to)(struct iio_buffer *buffer, u8 *data); + int (*store_to)(struct iio_buffer *buffer, const void *data); int (*read_first_n)(struct iio_buffer *buffer, size_t n, char __user *buf); @@ -81,7 +81,7 @@ struct iio_buffer { bool stufftoread; const struct attribute_group *attrs; struct list_head demux_list; - unsigned char *demux_bounce; + void *demux_bounce; struct list_head buffer_list; }; @@ -120,7 +120,32 @@ int iio_scan_mask_set(struct iio_dev *indio_dev, * @indio_dev: iio_dev structure for device. * @data: Full scan. */ -int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data); +int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data); + +/* + * iio_push_to_buffers_with_timestamp() - push data and timestamp to buffers + * @indio_dev: iio_dev structure for device. + * @data: sample data + * @timestamp: timestamp for the sample data + * + * Pushes data to the IIO device's buffers. If timestamps are enabled for the + * device the function will store the supplied timestamp as the last element in + * the sample data buffer before pushing it to the device buffers. The sample + * data buffer needs to be large enough to hold the additional timestamp + * (usually the buffer should be indio->scan_bytes bytes large). + * + * Returns 0 on success, a negative error code otherwise. + */ +static inline int iio_push_to_buffers_with_timestamp(struct iio_dev *indio_dev, + void *data, int64_t timestamp) +{ + if (indio_dev->scan_timestamp) { + size_t ts_offset = indio_dev->scan_bytes / sizeof(int64_t) - 1; + ((int64_t *)data)[ts_offset] = timestamp; + } + + return iio_push_to_buffers(indio_dev, data); +} int iio_update_demux(struct iio_dev *indio_dev); diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index 1f86a97ab2e2..e732fda6c8e6 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h @@ -15,6 +15,9 @@ #include <linux/spi/spi.h> #include <linux/irqreturn.h> #include <linux/iio/trigger.h> +#include <linux/bitops.h> + +#include <linux/platform_data/st_sensors_pdata.h> #define ST_SENSORS_TX_MAX_LENGTH 2 #define ST_SENSORS_RX_MAX_LENGTH 6 @@ -23,14 +26,10 @@ #define ST_SENSORS_FULLSCALE_AVL_MAX 10 #define ST_SENSORS_NUMBER_ALL_CHANNELS 4 -#define ST_SENSORS_NUMBER_DATA_CHANNELS 3 #define ST_SENSORS_ENABLE_ALL_AXIS 0x07 -#define ST_SENSORS_BYTE_FOR_CHANNEL 2 #define ST_SENSORS_SCAN_X 0 #define ST_SENSORS_SCAN_Y 1 #define ST_SENSORS_SCAN_Z 2 -#define ST_SENSORS_DEFAULT_12_REALBITS 12 -#define ST_SENSORS_DEFAULT_16_REALBITS 16 #define ST_SENSORS_DEFAULT_POWER_ON_VALUE 0x01 #define ST_SENSORS_DEFAULT_POWER_OFF_VALUE 0x00 #define ST_SENSORS_DEFAULT_WAI_ADDRESS 0x0f @@ -41,20 +40,20 @@ #define ST_SENSORS_MAX_NAME 17 #define ST_SENSORS_MAX_4WAI 7 -#define ST_SENSORS_LSM_CHANNELS(device_type, index, mod, endian, bits, addr) \ +#define ST_SENSORS_LSM_CHANNELS(device_type, mask, index, mod, \ + ch2, s, endian, rbits, sbits, addr) \ { \ .type = device_type, \ - .modified = 1, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .modified = mod, \ + .info_mask_separate = mask, \ .scan_index = index, \ - .channel2 = mod, \ + .channel2 = ch2, \ .address = addr, \ .scan_type = { \ - .sign = 's', \ - .realbits = bits, \ - .shift = 16 - bits, \ - .storagebits = 16, \ + .sign = s, \ + .realbits = rbits, \ + .shift = sbits - rbits, \ + .storagebits = sbits, \ .endianness = endian, \ }, \ } @@ -121,14 +120,16 @@ struct st_sensor_bdu { /** * struct st_sensor_data_ready_irq - ST sensor device data-ready interrupt * @addr: address of the register. - * @mask: mask to write the on/off value. + * @mask_int1: mask to enable/disable IRQ on INT1 pin. + * @mask_int2: mask to enable/disable IRQ on INT2 pin. * struct ig1 - represents the Interrupt Generator 1 of sensors. * @en_addr: address of the enable ig1 register. * @en_mask: mask to write the on/off value for enable. */ struct st_sensor_data_ready_irq { u8 addr; - u8 mask; + u8 mask_int1; + u8 mask_int2; struct { u8 en_addr; u8 en_mask; @@ -183,6 +184,7 @@ struct st_sensors { u8 wai; char sensors_supported[ST_SENSORS_MAX_4WAI][ST_SENSORS_MAX_NAME]; struct iio_chan_spec *ch; + int num_ch; struct st_sensor_odr odr; struct st_sensor_power pw; struct st_sensor_axis enable_axis; @@ -203,6 +205,8 @@ struct st_sensors { * @multiread_bit: Use or not particular bit for [I2C/SPI] multiread. * @buffer_data: Data used by buffer part. * @odr: Output data rate of the sensor [Hz]. + * num_data_channels: Number of data channels used in buffer. + * @drdy_int_pin: Redirect DRDY on pin 1 (1) or pin 2 (2). * @get_irq_data_ready: Function to get the IRQ used for data ready signal. * @tf: Transfer function structure used by I/O operations. * @tb: Transfer buffers and mutex used by I/O operations. @@ -219,6 +223,9 @@ struct st_sensor_data { char *buffer_data; unsigned int odr; + unsigned int num_data_channels; + + u8 drdy_int_pin; unsigned int (*get_irq_data_ready) (struct iio_dev *indio_dev); @@ -227,14 +234,17 @@ struct st_sensor_data { }; #ifdef CONFIG_IIO_BUFFER +irqreturn_t st_sensors_trigger_handler(int irq, void *p); + +int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf); +#endif + +#ifdef CONFIG_IIO_TRIGGER int st_sensors_allocate_trigger(struct iio_dev *indio_dev, const struct iio_trigger_ops *trigger_ops); void st_sensors_deallocate_trigger(struct iio_dev *indio_dev); -irqreturn_t st_sensors_trigger_handler(int irq, void *p); - -int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf); #else static inline int st_sensors_allocate_trigger(struct iio_dev *indio_dev, const struct iio_trigger_ops *trigger_ops) @@ -247,7 +257,8 @@ static inline void st_sensors_deallocate_trigger(struct iio_dev *indio_dev) } #endif -int st_sensors_init_sensor(struct iio_dev *indio_dev); +int st_sensors_init_sensor(struct iio_dev *indio_dev, + struct st_sensors_platform_data *pdata); int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable); diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index 833926c91aa8..2752b1fd12be 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -77,7 +77,7 @@ struct iio_cb_buffer; * fail. */ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev, - int (*cb)(u8 *data, + int (*cb)(const void *data, void *private), void *private); /** diff --git a/include/linux/iio/frequency/adf4350.h b/include/linux/iio/frequency/adf4350.h index be91f344d5fc..ffd8c8f90928 100644 --- a/include/linux/iio/frequency/adf4350.h +++ b/include/linux/iio/frequency/adf4350.h @@ -1,7 +1,7 @@ /* * ADF4350/ADF4351 SPI PLL driver * - * Copyright 2012 Analog Devices Inc. + * Copyright 2012-2013 Analog Devices Inc. * * Licensed under the GPL-2. */ @@ -41,7 +41,7 @@ #define ADF4350_REG2_RDIV2_EN (1 << 24) #define ADF4350_REG2_RMULT2_EN (1 << 25) #define ADF4350_REG2_MUXOUT(x) ((x) << 26) -#define ADF4350_REG2_NOISE_MODE(x) ((x) << 29) +#define ADF4350_REG2_NOISE_MODE(x) (((unsigned)(x)) << 29) #define ADF4350_MUXOUT_THREESTATE 0 #define ADF4350_MUXOUT_DVDD 1 #define ADF4350_MUXOUT_GND 2 diff --git a/include/linux/iio/gyro/itg3200.h b/include/linux/iio/gyro/itg3200.h index c53f16914b77..2a820850f284 100644 --- a/include/linux/iio/gyro/itg3200.h +++ b/include/linux/iio/gyro/itg3200.h @@ -149,6 +149,6 @@ static inline void itg3200_buffer_unconfigure(struct iio_dev *indio_dev) { } -#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* CONFIG_IIO_BUFFER */ #endif /* ITG3200_H_ */ diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index da8c776ba0bd..ac1cb8f1858c 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -36,77 +36,15 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_PHASE, IIO_CHAN_INFO_HARDWAREGAIN, IIO_CHAN_INFO_HYSTERESIS, + IIO_CHAN_INFO_INT_TIME, }; -#define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) -#define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1) -#define IIO_CHAN_INFO_BITS(type) (IIO_CHAN_INFO_SHARED_BIT(type) | \ - IIO_CHAN_INFO_SEPARATE_BIT(type)) - -#define IIO_CHAN_INFO_RAW_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_RAW) -#define IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PROCESSED) -#define IIO_CHAN_INFO_SCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SCALE) -#define IIO_CHAN_INFO_SCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SCALE) -#define IIO_CHAN_INFO_OFFSET_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_OFFSET) -#define IIO_CHAN_INFO_OFFSET_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_OFFSET) -#define IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBSCALE) -#define IIO_CHAN_INFO_CALIBSCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBSCALE) -#define IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBBIAS) -#define IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBBIAS) -#define IIO_CHAN_INFO_PEAK_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAK) -#define IIO_CHAN_INFO_PEAK_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAK) -#define IIO_CHAN_INFO_PEAKSCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAKSCALE) -#define IIO_CHAN_INFO_PEAKSCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAKSCALE) -#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT( \ - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) -#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT( \ - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) -#define IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_AVERAGE_RAW) -#define IIO_CHAN_INFO_AVERAGE_RAW_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_AVERAGE_RAW) -#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT( \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) -#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT( \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) -#define IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SAMP_FREQ) -#define IIO_CHAN_INFO_SAMP_FREQ_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SAMP_FREQ) -#define IIO_CHAN_INFO_FREQUENCY_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_FREQUENCY) -#define IIO_CHAN_INFO_FREQUENCY_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_FREQUENCY) -#define IIO_CHAN_INFO_PHASE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PHASE) -#define IIO_CHAN_INFO_PHASE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PHASE) -#define IIO_CHAN_INFO_HARDWAREGAIN_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_HARDWAREGAIN) -#define IIO_CHAN_INFO_HARDWAREGAIN_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_HARDWAREGAIN) -#define IIO_CHAN_INFO_HYSTERESIS_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_HYSTERESIS) -#define IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_HYSTERESIS) +enum iio_shared_by { + IIO_SEPARATE, + IIO_SHARED_BY_TYPE, + IIO_SHARED_BY_DIR, + IIO_SHARED_BY_ALL +}; enum iio_endian { IIO_CPU, @@ -127,7 +65,7 @@ struct iio_dev; */ struct iio_chan_spec_ext_info { const char *name; - bool shared; + enum iio_shared_by shared; ssize_t (*read)(struct iio_dev *, uintptr_t private, struct iio_chan_spec const *, char *buf); ssize_t (*write)(struct iio_dev *, uintptr_t private, @@ -195,7 +133,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, #define IIO_ENUM_AVAILABLE(_name, _e) \ { \ .name = (_name "_available"), \ - .shared = true, \ + .shared = IIO_SHARED_BY_TYPE, \ .read = iio_enum_available_read, \ .private = (uintptr_t)(_e), \ } @@ -216,8 +154,14 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * shift: Shift right by this before masking out * realbits. * endianness: little or big endian - * @info_mask: What information is to be exported about this channel. - * This includes calibbias, scale etc. + * @info_mask_separate: What information is to be exported that is specific to + * this channel. + * @info_mask_shared_by_type: What information is to be exported that is shared + * by all channels of the same type. + * @info_mask_shared_by_dir: What information is to be exported that is shared + * by all channels of the same direction. + * @info_mask_shared_by_all: What information is to be exported that is shared + * by all channels. * @event_mask: What events can this channel produce. * @ext_info: Array of extended info attributes for this channel. * The array is NULL terminated, the last element should @@ -252,7 +196,10 @@ struct iio_chan_spec { u8 shift; enum iio_endian endianness; } scan_type; - long info_mask; + long info_mask_separate; + long info_mask_shared_by_type; + long info_mask_shared_by_dir; + long info_mask_shared_by_all; long event_mask; const struct iio_chan_spec_ext_info *ext_info; const char *extend_name; @@ -275,7 +222,10 @@ struct iio_chan_spec { static inline bool iio_channel_has_info(const struct iio_chan_spec *chan, enum iio_chan_info_enum type) { - return chan->info_mask & IIO_CHAN_INFO_BITS(type); + return (chan->info_mask_separate & BIT(type)) | + (chan->info_mask_shared_by_type & BIT(type)) | + (chan->info_mask_shared_by_dir & BIT(type)) | + (chan->info_mask_shared_by_all & BIT(type)); } #define IIO_ST(si, rb, sb, sh) \ @@ -520,7 +470,7 @@ static inline void iio_device_put(struct iio_dev *indio_dev) { if (indio_dev) put_device(&indio_dev->dev); -}; +} /** * dev_to_iio_dev() - Get IIO device struct from a device struct @@ -595,6 +545,60 @@ static inline struct iio_dev *iio_priv_to_dev(void *priv) void iio_device_free(struct iio_dev *indio_dev); /** + * devm_iio_device_alloc - Resource-managed iio_device_alloc() + * @dev: Device to allocate iio_dev for + * @sizeof_priv: Space to allocate for private structure. + * + * Managed iio_device_alloc. iio_dev allocated with this function is + * automatically freed on driver detach. + * + * If an iio_dev allocated with this function needs to be freed separately, + * devm_iio_device_free() must be used. + * + * RETURNS: + * Pointer to allocated iio_dev on success, NULL on failure. + */ +struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv); + +/** + * devm_iio_device_free - Resource-managed iio_device_free() + * @dev: Device this iio_dev belongs to + * @indio_dev: the iio_dev associated with the device + * + * Free iio_dev allocated with devm_iio_device_alloc(). + */ +void devm_iio_device_free(struct device *dev, struct iio_dev *indio_dev); + +/** + * devm_iio_trigger_alloc - Resource-managed iio_trigger_alloc() + * @dev: Device to allocate iio_trigger for + * @fmt: trigger name format. If it includes format + * specifiers, the additional arguments following + * format are formatted and inserted in the resulting + * string replacing their respective specifiers. + * + * Managed iio_trigger_alloc. iio_trigger allocated with this function is + * automatically freed on driver detach. + * + * If an iio_trigger allocated with this function needs to be freed separately, + * devm_iio_trigger_free() must be used. + * + * RETURNS: + * Pointer to allocated iio_trigger on success, NULL on failure. + */ +struct iio_trigger *devm_iio_trigger_alloc(struct device *dev, + const char *fmt, ...); + +/** + * devm_iio_trigger_free - Resource-managed iio_trigger_free() + * @dev: Device this iio_dev belongs to + * @iio_trig: the iio_trigger associated with the device + * + * Free iio_trigger allocated with devm_iio_trigger_alloc(). + */ +void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig); + +/** * iio_buffer_enabled() - helper function to test if the buffer is enabled * @indio_dev: IIO device structure for device **/ @@ -602,7 +606,7 @@ static inline bool iio_buffer_enabled(struct iio_dev *indio_dev) { return indio_dev->currentmode & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE); -}; +} /** * iio_get_debugfs_dentry() - helper function to get the debugfs_dentry @@ -612,12 +616,12 @@ static inline bool iio_buffer_enabled(struct iio_dev *indio_dev) static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) { return indio_dev->debugfs_dentry; -}; +} #else static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) { return NULL; -}; +} #endif int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer, diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index ff781dca2e9a..b665dc7f017b 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -162,8 +162,8 @@ int adis_single_conversion(struct iio_dev *indio_dev, .indexed = 1, \ .channel = (chan), \ .extend_name = name, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ .address = (addr), \ .scan_index = (si), \ .scan_type = { \ @@ -184,9 +184,9 @@ int adis_single_conversion(struct iio_dev *indio_dev, .type = IIO_TEMP, \ .indexed = 1, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ .address = (addr), \ .scan_index = (si), \ .scan_type = { \ @@ -197,13 +197,13 @@ int adis_single_conversion(struct iio_dev *indio_dev, }, \ } -#define ADIS_MOD_CHAN(_type, mod, addr, si, info, bits) { \ +#define ADIS_MOD_CHAN(_type, mod, addr, si, info_sep, bits) { \ .type = (_type), \ .modified = 1, \ .channel2 = IIO_MOD_ ## mod, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - info, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + info_sep, \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = (addr), \ .scan_index = (si), \ .scan_type = { \ @@ -214,17 +214,17 @@ int adis_single_conversion(struct iio_dev *indio_dev, }, \ } -#define ADIS_ACCEL_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info, bits) +#define ADIS_ACCEL_CHAN(mod, addr, si, info_sep, bits) \ + ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info_sep, bits) -#define ADIS_GYRO_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info, bits) +#define ADIS_GYRO_CHAN(mod, addr, si, info_sep, bits) \ + ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info_sep, bits) -#define ADIS_INCLI_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info, bits) +#define ADIS_INCLI_CHAN(mod, addr, si, info_sep, bits) \ + ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info_sep, bits) -#define ADIS_ROT_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info, bits) +#define ADIS_ROT_CHAN(mod, addr, si, info_sep, bits) \ + ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info_sep, bits) #ifdef CONFIG_IIO_ADIS_LIB_BUFFER diff --git a/include/linux/iio/sysfs.h b/include/linux/iio/sysfs.h index b7a934b9431b..8a1d18640ab9 100644 --- a/include/linux/iio/sysfs.h +++ b/include/linux/iio/sysfs.h @@ -73,11 +73,6 @@ struct iio_const_attr { .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)} /* Generic attributes of onetype or another */ -/** - * IIO_DEV_ATTR_RESET: resets the device - **/ -#define IIO_DEV_ATTR_RESET(_store) \ - IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, _store, 0) /** * IIO_DEV_ATTR_SAMP_FREQ - sets any internal clock frequency @@ -105,6 +100,21 @@ struct iio_const_attr { #define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string) \ IIO_CONST_ATTR(sampling_frequency_available, _string) +/** + * IIO_DEV_ATTR_INT_TIME_AVAIL - list available integration times + * @_show: output method for the attribute + **/ +#define IIO_DEV_ATTR_INT_TIME_AVAIL(_show) \ + IIO_DEVICE_ATTR(integration_time_available, S_IRUGO, _show, NULL, 0) +/** + * IIO_CONST_ATTR_INT_TIME_AVAIL - list available integration times + * @_string: frequency string for the attribute + * + * Constant version + **/ +#define IIO_CONST_ATTR_INT_TIME_AVAIL(_string) \ + IIO_CONST_ATTR(integration_time_available, _string) + #define IIO_DEV_ATTR_TEMP_RAW(_show) \ IIO_DEVICE_ATTR(in_temp_raw, S_IRUGO, _show, NULL, 0) diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h index c66e0a96f6e8..369cf2cd5144 100644 --- a/include/linux/iio/trigger.h +++ b/include/linux/iio/trigger.h @@ -8,6 +8,7 @@ */ #include <linux/irq.h> #include <linux/module.h> +#include <linux/atomic.h> #ifndef _IIO_TRIGGER_H_ #define _IIO_TRIGGER_H_ @@ -44,7 +45,6 @@ struct iio_trigger_ops { * @id: [INTERN] unique id number * @name: [DRIVER] unique name * @dev: [DRIVER] associated device (if relevant) - * @private_data: [DRIVER] device specific data * @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 @@ -60,10 +60,9 @@ struct iio_trigger { const char *name; struct device dev; - void *private_data; struct list_head list; struct list_head alloc_list; - int use_count; + atomic_t use_count; struct irq_chip subirq_chip; int subirq_base; @@ -92,6 +91,30 @@ static inline void iio_trigger_get(struct iio_trigger *trig) } /** + * iio_device_set_drvdata() - Set trigger driver data + * @trig: IIO trigger structure + * @data: Driver specific data + * + * Allows to attach an arbitrary pointer to an IIO trigger, which can later be + * retrieved by iio_trigger_get_drvdata(). + */ +static inline void iio_trigger_set_drvdata(struct iio_trigger *trig, void *data) +{ + dev_set_drvdata(&trig->dev, data); +} + +/** + * iio_trigger_get_drvdata() - Get trigger driver data + * @trig: IIO trigger structure + * + * Returns the data previously set with iio_trigger_set_drvdata() + */ +static inline void *iio_trigger_get_drvdata(struct iio_trigger *trig) +{ + return dev_get_drvdata(&trig->dev); +} + +/** * iio_trigger_register() - register a trigger with the IIO core * @trig_info: trigger to be registered **/ diff --git a/include/linux/ima.h b/include/linux/ima.h index 86c361e947b9..1b7f268cddce 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -46,7 +46,7 @@ static inline int ima_module_check(struct file *file) return 0; } -#endif /* CONFIG_IMA_H */ +#endif /* CONFIG_IMA */ #ifdef CONFIG_IMA_APPRAISE extern void ima_inode_post_setattr(struct dentry *dentry); @@ -72,5 +72,5 @@ static inline int ima_inode_removexattr(struct dentry *dentry, { return 0; } -#endif /* CONFIG_IMA_APPRAISE_H */ +#endif /* CONFIG_IMA_APPRAISE */ #endif /* _LINUX_IMA_H */ diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index ea1e3b863890..79640e015a86 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -5,57 +5,30 @@ #include <linux/bitmap.h> #include <linux/if.h> +#include <linux/ip.h> #include <linux/netdevice.h> #include <linux/rcupdate.h> #include <linux/timer.h> #include <linux/sysctl.h> #include <linux/rtnetlink.h> -enum -{ - IPV4_DEVCONF_FORWARDING=1, - IPV4_DEVCONF_MC_FORWARDING, - IPV4_DEVCONF_PROXY_ARP, - IPV4_DEVCONF_ACCEPT_REDIRECTS, - IPV4_DEVCONF_SECURE_REDIRECTS, - IPV4_DEVCONF_SEND_REDIRECTS, - IPV4_DEVCONF_SHARED_MEDIA, - IPV4_DEVCONF_RP_FILTER, - IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE, - IPV4_DEVCONF_BOOTP_RELAY, - IPV4_DEVCONF_LOG_MARTIANS, - IPV4_DEVCONF_TAG, - IPV4_DEVCONF_ARPFILTER, - IPV4_DEVCONF_MEDIUM_ID, - IPV4_DEVCONF_NOXFRM, - IPV4_DEVCONF_NOPOLICY, - IPV4_DEVCONF_FORCE_IGMP_VERSION, - IPV4_DEVCONF_ARP_ANNOUNCE, - IPV4_DEVCONF_ARP_IGNORE, - IPV4_DEVCONF_PROMOTE_SECONDARIES, - IPV4_DEVCONF_ARP_ACCEPT, - IPV4_DEVCONF_ARP_NOTIFY, - IPV4_DEVCONF_ACCEPT_LOCAL, - IPV4_DEVCONF_SRC_VMARK, - IPV4_DEVCONF_PROXY_ARP_PVLAN, - IPV4_DEVCONF_ROUTE_LOCALNET, - __IPV4_DEVCONF_MAX -}; - -#define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1) - struct ipv4_devconf { void *sysctl; int data[IPV4_DEVCONF_MAX]; DECLARE_BITMAP(state, IPV4_DEVCONF_MAX); }; +#define MC_HASH_SZ_LOG 9 + struct in_device { struct net_device *dev; atomic_t refcnt; int dead; struct in_ifaddr *ifa_list; /* IP ifaddr chain */ + struct ip_mc_list __rcu *mc_list; /* IP multicast filter chain */ + struct ip_mc_list __rcu * __rcu *mc_hash; + int mc_count; /* Number of installed mcasts */ spinlock_t mc_tomb_lock; struct ip_mc_list *mc_tomb; diff --git a/include/linux/init.h b/include/linux/init.h index 861814710d52..f1c27a71d03c 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -93,13 +93,13 @@ #define __exit __section(.exit.text) __exitused __cold notrace -/* Used for HOTPLUG_CPU */ -#define __cpuinit __section(.cpuinit.text) __cold notrace -#define __cpuinitdata __section(.cpuinit.data) -#define __cpuinitconst __constsection(.cpuinit.rodata) -#define __cpuexit __section(.cpuexit.text) __exitused __cold notrace -#define __cpuexitdata __section(.cpuexit.data) -#define __cpuexitconst __constsection(.cpuexit.rodata) +/* temporary, until all users are removed */ +#define __cpuinit +#define __cpuinitdata +#define __cpuinitconst +#define __cpuexit +#define __cpuexitdata +#define __cpuexitconst /* Used for MEMORY_HOTPLUG */ #define __meminit __section(.meminit.text) __cold notrace @@ -118,9 +118,8 @@ #define __INITRODATA .section ".init.rodata","a",%progbits #define __FINITDATA .previous -#define __CPUINIT .section ".cpuinit.text", "ax" -#define __CPUINITDATA .section ".cpuinit.data", "aw" -#define __CPUINITRODATA .section ".cpuinit.rodata", "a" +/* temporary, until all users are removed */ +#define __CPUINIT #define __MEMINIT .section ".meminit.text", "ax" #define __MEMINITDATA .section ".meminit.data", "aw" @@ -154,6 +153,7 @@ extern unsigned int reset_devices; void setup_arch(char **); void prepare_namespace(void); void __init load_default_modules(void); +int __init init_rootfs(void); extern void (*late_time_init)(void); diff --git a/include/linux/input/auo-pixcir-ts.h b/include/linux/input/auo-pixcir-ts.h index 75d4be717714..5049f21928e4 100644 --- a/include/linux/input/auo-pixcir-ts.h +++ b/include/linux/input/auo-pixcir-ts.h @@ -43,12 +43,10 @@ */ struct auo_pixcir_ts_platdata { int gpio_int; + int gpio_rst; int int_setting; - void (*init_hw)(struct i2c_client *); - void (*exit_hw)(struct i2c_client *); - unsigned int x_max; unsigned int y_max; }; diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h index 5f3aa6b11bfa..27e06acc509a 100644 --- a/include/linux/input/matrix_keypad.h +++ b/include/linux/input/matrix_keypad.h @@ -81,4 +81,23 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, unsigned short *keymap, struct input_dev *input_dev); +#ifdef CONFIG_OF +/** + * matrix_keypad_parse_of_params() - Read parameters from matrix-keypad node + * + * @dev: Device containing of_node + * @rows: Returns number of matrix rows + * @cols: Returns number of matrix columns + * @return 0 if OK, <0 on error + */ +int matrix_keypad_parse_of_params(struct device *dev, + unsigned int *rows, unsigned int *cols); +#else +static inline int matrix_keypad_parse_of_params(struct device *dev, + unsigned int *rows, unsigned int *cols) +{ + return -ENOSYS; +} +#endif /* CONFIG_OF */ + #endif /* _MATRIX_KEYPAD_H */ diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index 2e86bd0bfba1..1b1dfa80d9ff 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h @@ -19,6 +19,7 @@ #define INPUT_MT_DIRECT 0x0002 /* direct device, e.g. touchscreen */ #define INPUT_MT_DROP_UNUSED 0x0004 /* drop contacts not seen in frame */ #define INPUT_MT_TRACK 0x0008 /* use in-kernel tracking */ +#define INPUT_MT_SEMI_MT 0x0010 /* semi-mt device, finger count handled manually */ /** * struct input_mt_slot - represents the state of an input MT slot diff --git a/include/linux/input/ti_am335x_tsc.h b/include/linux/input/ti_am335x_tsc.h deleted file mode 100644 index 49269a2aa329..000000000000 --- a/include/linux/input/ti_am335x_tsc.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __LINUX_TI_AM335X_TSC_H -#define __LINUX_TI_AM335X_TSC_H - -/** - * struct tsc_data Touchscreen wire configuration - * @wires: Wires refer to application modes - * i.e. 4/5/8 wire touchscreen support - * on the platform. - * @x_plate_resistance: X plate resistance. - * @steps_to_configure: The sequencer supports a total of - * 16 programmable steps. - * A step configured to read a single - * co-ordinate value, can be applied - * more number of times for better results. - */ - -struct tsc_data { - int wires; - int x_plate_resistance; - int steps_to_configure; -}; - -#endif diff --git a/include/linux/input/tps6507x-ts.h b/include/linux/input/tps6507x-ts.h index ab1440313924..b433df801d92 100644 --- a/include/linux/input/tps6507x-ts.h +++ b/include/linux/input/tps6507x-ts.h @@ -14,7 +14,6 @@ /* Board specific touch screen initial values */ struct touchscreen_init_data { int poll_period; /* ms */ - int vref; /* non-zero to leave vref on */ __u16 min_pressure; /* min reading to be treated as a touch */ __u16 vendor; __u16 product; diff --git a/include/linux/integrity.h b/include/linux/integrity.h index 66c5fe9550a5..83222cebd47b 100644 --- a/include/linux/integrity.h +++ b/include/linux/integrity.h @@ -36,5 +36,5 @@ static inline void integrity_inode_free(struct inode *inode) { return; } -#endif /* CONFIG_INTEGRITY_H */ +#endif /* CONFIG_INTEGRITY */ #endif /* _LINUX_INTEGRITY_H */ diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 78e2ada50cd5..d380c5e68008 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -55,7 +55,7 @@ #define DMAR_IQT_REG 0x88 /* Invalidation queue tail register */ #define DMAR_IQ_SHIFT 4 /* Invalidation queue head/tail shift */ #define DMAR_IQA_REG 0x90 /* Invalidation queue addr register */ -#define DMAR_ICS_REG 0x98 /* Invalidation complete status register */ +#define DMAR_ICS_REG 0x9c /* Invalidation complete status register */ #define DMAR_IRTA_REG 0xb8 /* Interrupt remapping table addr register */ #define OFFSET_STRIDE (9) diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 5fa5afeeb759..5e865b554940 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -120,7 +120,6 @@ struct irqaction { extern irqreturn_t no_action(int cpl, void *dev_id); -#ifdef CONFIG_GENERIC_HARDIRQS extern int __must_check request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn, @@ -140,40 +139,6 @@ request_any_context_irq(unsigned int irq, irq_handler_t handler, extern int __must_check request_percpu_irq(unsigned int irq, irq_handler_t handler, const char *devname, void __percpu *percpu_dev_id); -#else - -extern int __must_check -request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, - const char *name, void *dev); - -/* - * Special function to avoid ifdeffery in kernel/irq/devres.c which - * gets magically built by GENERIC_HARDIRQS=n architectures (sparc, - * m68k). I really love these $@%#!* obvious Makefile references: - * ../../../kernel/irq/devres.o - */ -static inline int __must_check -request_threaded_irq(unsigned int irq, irq_handler_t handler, - irq_handler_t thread_fn, - unsigned long flags, const char *name, void *dev) -{ - return request_irq(irq, handler, flags, name, dev); -} - -static inline int __must_check -request_any_context_irq(unsigned int irq, irq_handler_t handler, - unsigned long flags, const char *name, void *dev_id) -{ - return request_irq(irq, handler, flags, name, dev_id); -} - -static inline int __must_check -request_percpu_irq(unsigned int irq, irq_handler_t handler, - const char *devname, void __percpu *percpu_dev_id) -{ - return request_irq(irq, handler, 0, devname, percpu_dev_id); -} -#endif extern void free_irq(unsigned int, void *); extern void free_percpu_irq(unsigned int, void __percpu *); @@ -221,7 +186,6 @@ extern void enable_irq(unsigned int irq); extern void enable_percpu_irq(unsigned int irq, unsigned int type); /* The following three functions are for the core kernel use only. */ -#ifdef CONFIG_GENERIC_HARDIRQS extern void suspend_device_irqs(void); extern void resume_device_irqs(void); #ifdef CONFIG_PM_SLEEP @@ -229,13 +193,8 @@ extern int check_wakeup_irqs(void); #else static inline int check_wakeup_irqs(void) { return 0; } #endif -#else -static inline void suspend_device_irqs(void) { }; -static inline void resume_device_irqs(void) { }; -static inline int check_wakeup_irqs(void) { return 0; } -#endif -#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS) +#if defined(CONFIG_SMP) extern cpumask_var_t irq_default_affinity; @@ -287,9 +246,8 @@ static inline int irq_set_affinity_hint(unsigned int irq, { return -EINVAL; } -#endif /* CONFIG_SMP && CONFIG_GENERIC_HARDIRQS */ +#endif /* CONFIG_SMP */ -#ifdef CONFIG_GENERIC_HARDIRQS /* * Special lockdep variants of irq disabling/enabling. * These should be used for locking constructs that @@ -354,33 +312,6 @@ static inline int disable_irq_wake(unsigned int irq) return irq_set_irq_wake(irq, 0); } -#else /* !CONFIG_GENERIC_HARDIRQS */ -/* - * NOTE: non-genirq architectures, if they want to support the lock - * validator need to define the methods below in their asm/irq.h - * files, under an #ifdef CONFIG_LOCKDEP section. - */ -#ifndef CONFIG_LOCKDEP -# define disable_irq_nosync_lockdep(irq) disable_irq_nosync(irq) -# define disable_irq_nosync_lockdep_irqsave(irq, flags) \ - disable_irq_nosync(irq) -# define disable_irq_lockdep(irq) disable_irq(irq) -# define enable_irq_lockdep(irq) enable_irq(irq) -# define enable_irq_lockdep_irqrestore(irq, flags) \ - enable_irq(irq) -# endif - -static inline int enable_irq_wake(unsigned int irq) -{ - return 0; -} - -static inline int disable_irq_wake(unsigned int irq) -{ - return 0; -} -#endif /* CONFIG_GENERIC_HARDIRQS */ - #ifdef CONFIG_IRQ_FORCED_THREADING extern bool force_irqthreads; @@ -655,7 +586,7 @@ void tasklet_hrtimer_cancel(struct tasklet_hrtimer *ttimer) * if more than one irq occurred. */ -#if defined(CONFIG_GENERIC_HARDIRQS) && !defined(CONFIG_GENERIC_IRQ_PROBE) +#if !defined(CONFIG_GENERIC_IRQ_PROBE) static inline unsigned long probe_irq_on(void) { return 0; diff --git a/include/linux/io.h b/include/linux/io.h index 069e4075f872..f4f42faec686 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -76,4 +76,29 @@ void devm_ioremap_release(struct device *dev, void *res); #define arch_has_dev_port() (1) #endif +/* + * Some systems (x86 without PAT) have a somewhat reliable way to mark a + * physical address range such that uncached mappings will actually + * end up write-combining. This facility should be used in conjunction + * with pgprot_writecombine, ioremap-wc, or set_memory_wc, since it has + * no effect if the per-page mechanisms are functional. + * (On x86 without PAT, these functions manipulate MTRRs.) + * + * arch_phys_del_wc(0) or arch_phys_del_wc(any error code) is guaranteed + * to have no effect. + */ +#ifndef arch_phys_wc_add +static inline int __must_check arch_phys_wc_add(unsigned long base, + unsigned long size) +{ + return 0; /* It worked (i.e. did nothing). */ +} + +static inline void arch_phys_wc_del(int handle) +{ +} + +#define arch_phys_wc_add arch_phys_wc_add +#endif + #endif /* _LINUX_IO_H */ diff --git a/include/linux/iommu.h b/include/linux/iommu.h index ba3b8a98a049..a444c790fa72 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -20,7 +20,9 @@ #define __LINUX_IOMMU_H #include <linux/errno.h> +#include <linux/err.h> #include <linux/types.h> +#include <trace/events/iommu.h> #define IOMMU_READ (1) #define IOMMU_WRITE (2) @@ -57,10 +59,26 @@ struct iommu_domain { #define IOMMU_CAP_CACHE_COHERENCY 0x1 #define IOMMU_CAP_INTR_REMAP 0x2 /* isolates device intrs */ +/* + * Following constraints are specifc to FSL_PAMUV1: + * -aperture must be power of 2, and naturally aligned + * -number of windows must be power of 2, and address space size + * of each window is determined by aperture size / # of windows + * -the actual size of the mapped region of a window must be power + * of 2 starting with 4KB and physical address must be naturally + * aligned. + * DOMAIN_ATTR_FSL_PAMUV1 corresponds to the above mentioned contraints. + * The caller can invoke iommu_domain_get_attr to check if the underlying + * iommu implementation supports these constraints. + */ + enum iommu_attr { DOMAIN_ATTR_GEOMETRY, DOMAIN_ATTR_PAGING, DOMAIN_ATTR_WINDOWS, + DOMAIN_ATTR_FSL_PAMU_STASH, + DOMAIN_ATTR_FSL_PAMU_ENABLE, + DOMAIN_ATTR_FSL_PAMUV1, DOMAIN_ATTR_MAX, }; @@ -91,8 +109,7 @@ struct iommu_ops { phys_addr_t paddr, size_t size, int prot); size_t (*unmap)(struct iommu_domain *domain, unsigned long iova, size_t size); - phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, - unsigned long iova); + phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova); int (*domain_has_cap)(struct iommu_domain *domain, unsigned long cap); int (*add_device)(struct device *dev); @@ -105,7 +122,7 @@ struct iommu_ops { /* Window handling functions */ int (*domain_window_enable)(struct iommu_domain *domain, u32 wnd_nr, - phys_addr_t paddr, u64 size); + phys_addr_t paddr, u64 size, int prot); void (*domain_window_disable)(struct iommu_domain *domain, u32 wnd_nr); /* Set the numer of window per domain */ int (*domain_set_windows)(struct iommu_domain *domain, u32 w_count); @@ -125,6 +142,7 @@ struct iommu_ops { extern int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops); extern bool iommu_present(struct bus_type *bus); extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus); +extern struct iommu_group *iommu_group_get_by_id(int id); extern void iommu_domain_free(struct iommu_domain *domain); extern int iommu_attach_device(struct iommu_domain *domain, struct device *dev); @@ -134,8 +152,7 @@ extern int iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot); extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size); -extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, - unsigned long iova); +extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova); extern int iommu_domain_has_cap(struct iommu_domain *domain, unsigned long cap); extern void iommu_set_fault_handler(struct iommu_domain *domain, @@ -171,7 +188,8 @@ extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr, /* Window handling function prototypes */ extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr, - phys_addr_t offset, u64 size); + phys_addr_t offset, u64 size, + int prot); extern void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr); /** * report_iommu_fault() - report about an IOMMU fault to the IOMMU framework @@ -210,6 +228,7 @@ static inline int report_iommu_fault(struct iommu_domain *domain, ret = domain->handler(domain, dev, iova, flags, domain->handler_token); + trace_io_page_fault(dev, iova, flags); return ret; } @@ -257,7 +276,7 @@ static inline int iommu_unmap(struct iommu_domain *domain, unsigned long iova, static inline int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr, phys_addr_t paddr, - u64 size) + u64 size, int prot) { return -ENODEV; } @@ -267,8 +286,7 @@ static inline void iommu_domain_window_disable(struct iommu_domain *domain, { } -static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, - unsigned long iova) +static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) { return 0; } diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 85ac9b9b72a2..89b7c24a36e9 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -192,6 +192,10 @@ extern struct resource * __request_region(struct resource *, extern int __check_region(struct resource *, resource_size_t, resource_size_t); extern void __release_region(struct resource *, resource_size_t, resource_size_t); +#ifdef CONFIG_MEMORY_HOTREMOVE +extern int release_mem_region_adjustable(struct resource *, resource_size_t, + resource_size_t); +#endif static inline int __deprecated check_region(resource_size_t s, resource_size_t n) diff --git a/include/linux/ipack.h b/include/linux/ipack.h index fea12cbb2aeb..1888e06ddf64 100644 --- a/include/linux/ipack.h +++ b/include/linux/ipack.h @@ -207,19 +207,41 @@ int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, void ipack_driver_unregister(struct ipack_driver *edrv); /** - * ipack_device_register -- register an IPack device with the kernel - * @dev: the new device to register. + * ipack_device_init -- initialize an IPack device + * @dev: the new device to initialize. * - * Register a new IPack device ("module" in IndustryPack jargon). The call - * is done by the carrier driver. The carrier should populate the fields - * bus and slot as well as the region array of @dev prior to calling this - * function. The rest of the fields will be allocated and populated - * during registration. + * Initialize a new IPack device ("module" in IndustryPack jargon). The call + * is done by the carrier driver. The carrier should populate the fields + * bus and slot as well as the region array of @dev prior to calling this + * function. The rest of the fields will be allocated and populated + * during initalization. * - * Return zero on success or error code on failure. + * Return zero on success or error code on failure. + * + * NOTE: _Never_ directly free @dev after calling this function, even + * if it returned an error! Always use ipack_put_device() to give up the + * reference initialized in this function instead. + */ +int ipack_device_init(struct ipack_device *dev); + +/** + * ipack_device_add -- Add an IPack device + * @dev: the new device to add. + * + * Add a new IPack device. The call is done by the carrier driver + * after calling ipack_device_init(). + * + * Return zero on success or error code on failure. + * + * NOTE: _Never_ directly free @dev after calling this function, even + * if it returned an error! Always use ipack_put_device() to give up the + * reference initialized in this function instead. */ -int ipack_device_register(struct ipack_device *dev); -void ipack_device_unregister(struct ipack_device *dev); +int ipack_device_add(struct ipack_device *dev); +void ipack_device_del(struct ipack_device *dev); + +void ipack_get_device(struct ipack_device *dev); +void ipack_put_device(struct ipack_device *dev); /** * DEFINE_IPACK_DEVICE_TABLE - macro used to describe a IndustryPack table diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h index ae221a7b5092..19c19a5eee29 100644 --- a/include/linux/ipc_namespace.h +++ b/include/linux/ipc_namespace.h @@ -22,7 +22,7 @@ struct ipc_ids { int in_use; unsigned short seq; unsigned short seq_max; - struct rw_semaphore rw_mutex; + struct rw_semaphore rwsem; struct idr ipcs_idr; int next_id; }; @@ -43,8 +43,8 @@ struct ipc_namespace { size_t shm_ctlmax; size_t shm_ctlall; + unsigned long shm_tot; int shm_ctlmni; - int shm_tot; /* * Defines whether IPC_RMID is forced for _all_ shm segments regardless * of shmctl() diff --git a/include/linux/ipmi-fru.h b/include/linux/ipmi-fru.h new file mode 100644 index 000000000000..4d3a76380e32 --- /dev/null +++ b/include/linux/ipmi-fru.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2012 CERN (www.cern.ch) + * Author: Alessandro Rubini <rubini@gnudd.com> + * + * Released according to the GNU GPL, version 2 or any later version. + * + * This work is part of the White Rabbit project, a research effort led + * by CERN, the European Institute for Nuclear Research. + */ +#ifndef __LINUX_IPMI_FRU_H__ +#define __LINUX_IPMI_FRU_H__ +#ifdef __KERNEL__ +# include <linux/types.h> +# include <linux/string.h> +#else +# include <stdint.h> +# include <string.h> +#endif + +/* + * These structures match the unaligned crap we have in FRU1011.pdf + * (http://download.intel.com/design/servers/ipmi/FRU1011.pdf) + */ + +/* chapter 8, page 5 */ +struct fru_common_header { + uint8_t format; /* 0x01 */ + uint8_t internal_use_off; /* multiple of 8 bytes */ + uint8_t chassis_info_off; /* multiple of 8 bytes */ + uint8_t board_area_off; /* multiple of 8 bytes */ + uint8_t product_area_off; /* multiple of 8 bytes */ + uint8_t multirecord_off; /* multiple of 8 bytes */ + uint8_t pad; /* must be 0 */ + uint8_t checksum; /* sum modulo 256 must be 0 */ +}; + +/* chapter 9, page 5 -- internal_use: not used by us */ + +/* chapter 10, page 6 -- chassis info: not used by us */ + +/* chapter 13, page 9 -- used by board_info_area below */ +struct fru_type_length { + uint8_t type_length; + uint8_t data[0]; +}; + +/* chapter 11, page 7 */ +struct fru_board_info_area { + uint8_t format; /* 0x01 */ + uint8_t area_len; /* multiple of 8 bytes */ + uint8_t language; /* I hope it's 0 */ + uint8_t mfg_date[3]; /* LSB, minutes since 1996-01-01 */ + struct fru_type_length tl[0]; /* type-length stuff follows */ + + /* + * the TL there are in order: + * Board Manufacturer + * Board Product Name + * Board Serial Number + * Board Part Number + * FRU File ID (may be null) + * more manufacturer-specific stuff + * 0xc1 as a terminator + * 0x00 pad to a multiple of 8 bytes - 1 + * checksum (sum of all stuff module 256 must be zero) + */ +}; + +enum fru_type { + FRU_TYPE_BINARY = 0x00, + FRU_TYPE_BCDPLUS = 0x40, + FRU_TYPE_ASCII6 = 0x80, + FRU_TYPE_ASCII = 0xc0, /* not ascii: depends on language */ +}; + +/* + * some helpers + */ +static inline struct fru_board_info_area *fru_get_board_area( + const struct fru_common_header *header) +{ + /* we know for sure that the header is 8 bytes in size */ + return (struct fru_board_info_area *)(header + header->board_area_off); +} + +static inline int fru_type(struct fru_type_length *tl) +{ + return tl->type_length & 0xc0; +} + +static inline int fru_length(struct fru_type_length *tl) +{ + return (tl->type_length & 0x3f) + 1; /* len of whole record */ +} + +/* assume ascii-latin1 encoding */ +static inline int fru_strlen(struct fru_type_length *tl) +{ + return fru_length(tl) - 1; +} + +static inline char *fru_strcpy(char *dest, struct fru_type_length *tl) +{ + int len = fru_strlen(tl); + memcpy(dest, tl->data, len); + dest[len] = '\0'; + return dest; +} + +static inline struct fru_type_length *fru_next_tl(struct fru_type_length *tl) +{ + return tl + fru_length(tl); +} + +static inline int fru_is_eof(struct fru_type_length *tl) +{ + return tl->type_length == 0xc1; +} + +/* + * External functions defined in fru-parse.c. + */ +extern int fru_header_cksum_ok(struct fru_common_header *header); +extern int fru_bia_cksum_ok(struct fru_board_info_area *bia); + +/* All these 4 return allocated strings by calling fru_alloc() */ +extern char *fru_get_board_manufacturer(struct fru_common_header *header); +extern char *fru_get_product_name(struct fru_common_header *header); +extern char *fru_get_serial_number(struct fru_common_header *header); +extern char *fru_get_part_number(struct fru_common_header *header); + +/* This must be defined by the caller of the above functions */ +extern void *fru_alloc(size_t size); + +#endif /* __LINUX_IMPI_FRU_H__ */ diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 850e95bc766c..28ea38439313 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -19,6 +19,8 @@ struct ipv6_devconf { __s32 rtr_solicit_interval; __s32 rtr_solicit_delay; __s32 force_mld_version; + __s32 mldv1_unsolicited_report_interval; + __s32 mldv2_unsolicited_report_interval; #ifdef CONFIG_IPV6_PRIVACY __s32 use_tempaddr; __s32 temp_valid_lft; @@ -48,6 +50,7 @@ struct ipv6_devconf { __s32 accept_dad; __s32 force_tllao; __s32 ndisc_notify; + __s32 suppress_frag_ndisc; void *sysctl; }; @@ -101,6 +104,7 @@ struct inet6_skb_parm { #define IP6SKB_FORWARDED 2 #define IP6SKB_REROUTED 4 #define IP6SKB_ROUTERALERT 8 +#define IP6SKB_FRAGMENTED 16 }; #define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb)) diff --git a/include/linux/irq.h b/include/linux/irq.h index bc4e06611958..56bb0dc8b7d4 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -119,6 +119,7 @@ struct irq_domain; /** * struct irq_data - per irq and irq chip data passed down to chip functions + * @mask: precomputed bitmask for accessing the chip registers * @irq: interrupt number * @hwirq: hardware interrupt number, local to the interrupt domain * @node: node index useful for balancing @@ -138,6 +139,7 @@ struct irq_domain; * irq_data. */ struct irq_data { + u32 mask; unsigned int irq; unsigned long hwirq; unsigned int node; @@ -294,6 +296,7 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) * @irq_suspend: function called from core code on suspend once per chip * @irq_resume: function called from core code on resume once per chip * @irq_pm_shutdown: function called from core code on shutdown once per chip + * @irq_calc_mask: Optional function to set irq_data.mask for special cases * @irq_print_chip: optional to print special chip info in show_interrupts * @flags: chip specific flags */ @@ -325,6 +328,8 @@ struct irq_chip { void (*irq_resume)(struct irq_data *data); void (*irq_pm_shutdown)(struct irq_data *data); + void (*irq_calc_mask)(struct irq_data *data); + void (*irq_print_chip)(struct irq_data *data, struct seq_file *p); unsigned long flags; @@ -377,8 +382,6 @@ extern void irq_cpu_online(void); extern void irq_cpu_offline(void); extern int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *cpumask); -#ifdef CONFIG_GENERIC_HARDIRQS - #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ) void irq_move_irq(struct irq_data *data); void irq_move_masked_irq(struct irq_data *data); @@ -579,6 +582,12 @@ static inline struct msi_desc *irq_data_get_msi(struct irq_data *d) return d->msi_desc; } +static inline u32 irq_get_trigger_type(unsigned int irq) +{ + struct irq_data *d = irq_get_irq_data(irq); + return d ? irqd_get_trigger_type(d) : 0; +} + int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, struct module *owner); @@ -644,6 +653,8 @@ struct irq_chip_regs { * @regs: Register offsets for this chip * @handler: Flow handler associated with this chip * @type: Chip can handle these flow types + * @mask_cache_priv: Cached mask register private to the chip type + * @mask_cache: Pointer to cached mask register * * A irq_generic_chip can have several instances of irq_chip_type when * it requires different functions and register offsets for different @@ -654,6 +665,8 @@ struct irq_chip_type { struct irq_chip_regs regs; irq_flow_handler_t handler; u32 type; + u32 mask_cache_priv; + u32 *mask_cache; }; /** @@ -662,13 +675,16 @@ struct irq_chip_type { * @reg_base: Register base address (virtual) * @irq_base: Interrupt base nr for this chip * @irq_cnt: Number of interrupts handled by this chip - * @mask_cache: Cached mask register + * @mask_cache: Cached mask register shared between all chip types * @type_cache: Cached type register * @polarity_cache: Cached polarity register * @wake_enabled: Interrupt can wakeup from suspend * @wake_active: Interrupt is marked as an wakeup from suspend source * @num_ct: Number of available irq_chip_type instances (usually 1) * @private: Private data for non generic chip callbacks + * @installed: bitfield to denote installed interrupts + * @unused: bitfield to denote unused interrupts + * @domain: irq domain pointer * @list: List head for keeping track of instances * @chip_types: Array of interrupt irq_chip_types * @@ -690,6 +706,9 @@ struct irq_chip_generic { u32 wake_active; unsigned int num_ct; void *private; + unsigned long installed; + unsigned long unused; + struct irq_domain *domain; struct list_head list; struct irq_chip_type chip_types[0]; }; @@ -700,10 +719,32 @@ struct irq_chip_generic { * @IRQ_GC_INIT_NESTED_LOCK: Set the lock class of the irqs to nested for * irq chips which need to call irq_set_wake() on * the parent irq. Usually GPIO implementations + * @IRQ_GC_MASK_CACHE_PER_TYPE: Mask cache is chip type private + * @IRQ_GC_NO_MASK: Do not calculate irq_data->mask */ enum irq_gc_flags { IRQ_GC_INIT_MASK_CACHE = 1 << 0, IRQ_GC_INIT_NESTED_LOCK = 1 << 1, + IRQ_GC_MASK_CACHE_PER_TYPE = 1 << 2, + IRQ_GC_NO_MASK = 1 << 3, +}; + +/* + * struct irq_domain_chip_generic - Generic irq chip data structure for irq domains + * @irqs_per_chip: Number of interrupts per chip + * @num_chips: Number of chips + * @irq_flags_to_set: IRQ* flags to set on irq setup + * @irq_flags_to_clear: IRQ* flags to clear on irq setup + * @gc_flags: Generic chip specific setup flags + * @gc: Array of pointers to generic interrupt chips + */ +struct irq_domain_chip_generic { + unsigned int irqs_per_chip; + unsigned int num_chips; + unsigned int irq_flags_to_clear; + unsigned int irq_flags_to_set; + enum irq_gc_flags gc_flags; + struct irq_chip_generic *gc[0]; }; /* Generic chip callback functions */ @@ -729,6 +770,14 @@ int irq_setup_alt_chip(struct irq_data *d, unsigned int type); void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, unsigned int clr, unsigned int set); +struct irq_chip_generic *irq_get_domain_generic_chip(struct irq_domain *d, unsigned int hw_irq); +int irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip, + int num_ct, const char *name, + irq_flow_handler_t handler, + unsigned int clr, unsigned int set, + enum irq_gc_flags flags); + + static inline struct irq_chip_type *irq_data_get_chip_type(struct irq_data *d) { return container_of(d->chip, struct irq_chip_type, chip); @@ -751,11 +800,4 @@ static inline void irq_gc_lock(struct irq_chip_generic *gc) { } static inline void irq_gc_unlock(struct irq_chip_generic *gc) { } #endif -#else /* !CONFIG_GENERIC_HARDIRQS */ - -extern struct msi_desc *irq_get_msi_desc(unsigned int irq); -extern int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry); - -#endif /* CONFIG_GENERIC_HARDIRQS */ - #endif /* _LINUX_IRQ_H */ diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h index f5dbce50466e..66017028dcb3 100644 --- a/include/linux/irq_work.h +++ b/include/linux/irq_work.h @@ -37,7 +37,7 @@ void irq_work_sync(struct irq_work *work); #ifdef CONFIG_IRQ_WORK bool irq_work_needs_cpu(void); #else -static bool irq_work_needs_cpu(void) { return false; } +static inline bool irq_work_needs_cpu(void) { return false; } #endif #endif /* _LINUX_IRQ_WORK_H */ diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h index e0006f1d35a0..14d79131f53d 100644 --- a/include/linux/irqchip.h +++ b/include/linux/irqchip.h @@ -11,6 +11,10 @@ #ifndef _LINUX_IRQCHIP_H #define _LINUX_IRQCHIP_H +#ifdef CONFIG_IRQCHIP void irqchip_init(void); +#else +static inline void irqchip_init(void) {} +#endif #endif diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 3fd8e4290a1c..46544e381bf9 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -31,6 +31,8 @@ #define GIC_DIST_TARGET 0x800 #define GIC_DIST_CONFIG 0xc00 #define GIC_DIST_SOFTINT 0xf00 +#define GIC_DIST_SGI_PENDING_CLEAR 0xf10 +#define GIC_DIST_SGI_PENDING_SET 0xf20 #define GICH_HCR 0x0 #define GICH_VTR 0x4 @@ -65,8 +67,8 @@ extern struct irq_chip gic_arch_extn; void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, u32 offset, struct device_node *); -void gic_secondary_init(unsigned int); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); +void gic_cpu_if_down(void); static inline void gic_init(unsigned int nr, int start, void __iomem *dist , void __iomem *cpu) @@ -74,6 +76,9 @@ static inline void gic_init(unsigned int nr, int start, gic_init_bases(nr, start, dist, cpu, 0, NULL); } +int gic_get_cpu_id(unsigned int cpu); +void gic_migrate_target(unsigned int new_cpu_id); + #endif /* __ASSEMBLY */ #endif diff --git a/include/linux/irqchip/chained_irq.h b/include/linux/irqchip/chained_irq.h new file mode 100644 index 000000000000..adf4c30f3af6 --- /dev/null +++ b/include/linux/irqchip/chained_irq.h @@ -0,0 +1,52 @@ +/* + * Chained IRQ handlers support. + * + * Copyright (C) 2011 ARM Ltd. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef __IRQCHIP_CHAINED_IRQ_H +#define __IRQCHIP_CHAINED_IRQ_H + +#include <linux/irq.h> + +/* + * Entry/exit functions for chained handlers where the primary IRQ chip + * may implement either fasteoi or level-trigger flow control. + */ +static inline void chained_irq_enter(struct irq_chip *chip, + struct irq_desc *desc) +{ + /* FastEOI controllers require no action on entry. */ + if (chip->irq_eoi) + return; + + if (chip->irq_mask_ack) { + chip->irq_mask_ack(&desc->irq_data); + } else { + chip->irq_mask(&desc->irq_data); + if (chip->irq_ack) + chip->irq_ack(&desc->irq_data); + } +} + +static inline void chained_irq_exit(struct irq_chip *chip, + struct irq_desc *desc) +{ + if (chip->irq_eoi) + chip->irq_eoi(&desc->irq_data); + else + chip->irq_unmask(&desc->irq_data); +} + +#endif /* __IRQCHIP_CHAINED_IRQ_H */ diff --git a/include/linux/irqchip/mmp.h b/include/linux/irqchip/mmp.h new file mode 100644 index 000000000000..c78a8921185d --- /dev/null +++ b/include/linux/irqchip/mmp.h @@ -0,0 +1,6 @@ +#ifndef __IRQCHIP_MMP_H +#define __IRQCHIP_MMP_H + +extern struct irq_chip icu_irq_chip; + +#endif /* __IRQCHIP_MMP_H */ diff --git a/include/linux/irqchip/mxs.h b/include/linux/irqchip/mxs.h new file mode 100644 index 000000000000..9039a538a919 --- /dev/null +++ b/include/linux/irqchip/mxs.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2013 Freescale Semiconductor, Inc. + * + * 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_IRQCHIP_MXS_H +#define __LINUX_IRQCHIP_MXS_H + +extern void icoll_handle_irq(struct pt_regs *); + +#endif diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 623325e2ff97..56fb646909dc 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -76,8 +76,6 @@ struct irq_desc { extern struct irq_desc irq_desc[NR_IRQS]; #endif -#ifdef CONFIG_GENERIC_HARDIRQS - static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc) { return &desc->irq_data; @@ -173,6 +171,5 @@ __irq_set_preflow_handler(unsigned int irq, irq_preflow_handler_t handler) desc->preflow_handler = handler; } #endif -#endif #endif diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 0d5b17bf5e51..c983ed18c332 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -66,52 +66,55 @@ struct irq_domain_ops { unsigned long *out_hwirq, unsigned int *out_type); }; +extern struct irq_domain_ops irq_generic_chip_ops; + +struct irq_domain_chip_generic; + /** * struct irq_domain - Hardware interrupt number translation object * @link: Element in global irq_domain list. - * @revmap_type: Method used for reverse mapping hwirq numbers to linux irq. This - * will be one of the IRQ_DOMAIN_MAP_* values. - * @revmap_data: Revmap method specific data. + * @name: Name of interrupt domain * @ops: pointer to irq_domain methods * @host_data: private data pointer for use by owner. Not touched by irq_domain * core code. - * @irq_base: Start of irq_desc range assigned to the irq_domain. The creator - * of the irq_domain is responsible for allocating the array of - * irq_desc structures. - * @nr_irq: Number of irqs managed by the irq domain - * @hwirq_base: Starting number for hwirqs managed by the irq domain - * @of_node: (optional) Pointer to device tree nodes associated with the - * irq_domain. Used when decoding device tree interrupt specifiers. + * + * Optional elements + * @of_node: Pointer to device tree nodes associated with the irq_domain. Used + * when decoding device tree interrupt specifiers. + * @gc: Pointer to a list of generic chips. There is a helper function for + * setting up one or more generic chips for interrupt controllers + * drivers using the generic chip library which uses this pointer. + * + * Revmap data, used internally by irq_domain + * @revmap_direct_max_irq: The largest hwirq that can be set for controllers that + * support direct mapping + * @revmap_size: Size of the linear map table @linear_revmap[] + * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map + * @linear_revmap: Linear table of hwirq->virq reverse mappings */ struct irq_domain { struct list_head link; - - /* type of reverse mapping_technique */ - unsigned int revmap_type; - union { - struct { - unsigned int size; - unsigned int first_irq; - irq_hw_number_t first_hwirq; - } legacy; - struct { - unsigned int size; - unsigned int *revmap; - } linear; - struct { - unsigned int max_irq; - } nomap; - struct radix_tree_root tree; - } revmap_data; + const char *name; const struct irq_domain_ops *ops; void *host_data; - irq_hw_number_t inval_irq; - /* Optional device node pointer */ + /* Optional data */ struct device_node *of_node; + struct irq_domain_chip_generic *gc; + + /* reverse map data. The linear map gets appended to the irq_domain */ + irq_hw_number_t hwirq_max; + unsigned int revmap_direct_max_irq; + unsigned int revmap_size; + struct radix_tree_root revmap_tree; + unsigned int linear_revmap[]; }; #ifdef CONFIG_IRQ_DOMAIN +struct irq_domain *__irq_domain_add(struct device_node *of_node, int size, + irq_hw_number_t hwirq_max, int direct_max, + const struct irq_domain_ops *ops, + void *host_data); struct irq_domain *irq_domain_add_simple(struct device_node *of_node, unsigned int size, unsigned int first_irq, @@ -123,21 +126,30 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, irq_hw_number_t first_hwirq, const struct irq_domain_ops *ops, void *host_data); -struct irq_domain *irq_domain_add_linear(struct device_node *of_node, +extern struct irq_domain *irq_find_host(struct device_node *node); +extern void irq_set_default_host(struct irq_domain *host); + +/** + * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain. + * @of_node: pointer to interrupt controller's device tree node. + * @size: Number of interrupts in the domain. + * @ops: map/unmap domain callbacks + * @host_data: Controller private data pointer + */ +static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_node, unsigned int size, const struct irq_domain_ops *ops, - void *host_data); -struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, + void *host_data) +{ + return __irq_domain_add(of_node, size, size, 0, ops, host_data); +} +static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, unsigned int max_irq, const struct irq_domain_ops *ops, - void *host_data); -struct irq_domain *irq_domain_add_tree(struct device_node *of_node, - const struct irq_domain_ops *ops, - void *host_data); - -extern struct irq_domain *irq_find_host(struct device_node *node); -extern void irq_set_default_host(struct irq_domain *host); - + void *host_data) +{ + return __irq_domain_add(of_node, 0, max_irq, max_irq, ops, host_data); +} static inline struct irq_domain *irq_domain_add_legacy_isa( struct device_node *of_node, const struct irq_domain_ops *ops, @@ -146,21 +158,40 @@ static inline struct irq_domain *irq_domain_add_legacy_isa( return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops, host_data); } +static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node, + const struct irq_domain_ops *ops, + void *host_data) +{ + return __irq_domain_add(of_node, 0, ~0, 0, ops, host_data); +} extern void irq_domain_remove(struct irq_domain *host); -extern int irq_domain_associate_many(struct irq_domain *domain, - unsigned int irq_base, - irq_hw_number_t hwirq_base, int count); -static inline int irq_domain_associate(struct irq_domain *domain, unsigned int irq, - irq_hw_number_t hwirq) -{ - return irq_domain_associate_many(domain, irq, hwirq, 1); -} +extern int irq_domain_associate(struct irq_domain *domain, unsigned int irq, + irq_hw_number_t hwirq); +extern void irq_domain_associate_many(struct irq_domain *domain, + unsigned int irq_base, + irq_hw_number_t hwirq_base, int count); extern unsigned int irq_create_mapping(struct irq_domain *host, irq_hw_number_t hwirq); extern void irq_dispose_mapping(unsigned int virq); + +/** + * irq_linear_revmap() - Find a linux irq from a hw irq number. + * @domain: domain owning this hardware interrupt + * @hwirq: hardware irq number in that domain space + * + * This is a fast path alternative to irq_find_mapping() that can be + * called directly by irq controller code to save a handful of + * instructions. It is always safe to call, but won't find irqs mapped + * using the radix tree. + */ +static inline unsigned int irq_linear_revmap(struct irq_domain *domain, + irq_hw_number_t hwirq) +{ + return hwirq < domain->revmap_size ? domain->linear_revmap[hwirq] : 0; +} extern unsigned int irq_find_mapping(struct irq_domain *host, irq_hw_number_t hwirq); extern unsigned int irq_create_direct_mapping(struct irq_domain *host); @@ -174,9 +205,6 @@ static inline int irq_create_identity_mapping(struct irq_domain *host, return irq_create_strict_mappings(host, hwirq, hwirq, 1); } -extern unsigned int irq_linear_revmap(struct irq_domain *host, - irq_hw_number_t hwirq); - extern const struct irq_domain_ops irq_domain_simple_ops; /* stock xlate functions */ @@ -190,14 +218,6 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr, const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_type); -#if defined(CONFIG_OF_IRQ) -extern void irq_domain_generate_simple(const struct of_device_id *match, - u64 phys_base, unsigned int irq_start); -#else /* CONFIG_OF_IRQ */ -static inline void irq_domain_generate_simple(const struct of_device_id *match, - u64 phys_base, unsigned int irq_start) { } -#endif /* !CONFIG_OF_IRQ */ - #else /* CONFIG_IRQ_DOMAIN */ static inline void irq_dispose_mapping(unsigned int virq) { } #endif /* !CONFIG_IRQ_DOMAIN */ diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h index 0a2dc46cdaf6..fdd5cc16c9c4 100644 --- a/include/linux/irqnr.h +++ b/include/linux/irqnr.h @@ -4,23 +4,6 @@ #include <uapi/linux/irqnr.h> -#ifndef CONFIG_GENERIC_HARDIRQS -#include <asm/irq.h> - -/* - * Wrappers for non-genirq architectures: - */ -#define nr_irqs NR_IRQS -#define irq_to_desc(irq) (&irq_desc[irq]) - -# define for_each_irq_desc(irq, desc) \ - for (irq = 0; irq < nr_irqs; irq++) - -# define for_each_irq_desc_reverse(irq, desc) \ - for (irq = nr_irqs - 1; irq >= 0; irq--) - -#else /* CONFIG_GENERIC_HARDIRQS */ - extern int nr_irqs; extern struct irq_desc *irq_to_desc(unsigned int irq); unsigned int irq_get_next_irq(unsigned int offset); @@ -50,8 +33,6 @@ unsigned int irq_get_next_irq(unsigned int offset); for (irq = irq_get_next_irq(0); irq < nr_irqs; \ irq = irq_get_next_irq(irq + 1)) -#endif /* CONFIG_GENERIC_HARDIRQS */ - #define for_each_irq_nr(irq) \ for (irq = 0; irq < nr_irqs; irq++) diff --git a/include/linux/jbd.h b/include/linux/jbd.h index c8f32975f0e4..31229e0be90b 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h @@ -27,7 +27,6 @@ #include <linux/buffer_head.h> #include <linux/journal-head.h> #include <linux/stddef.h> -#include <linux/bit_spinlock.h> #include <linux/mutex.h> #include <linux/timer.h> #include <linux/lockdep.h> @@ -58,16 +57,13 @@ #define JBD_EXPENSIVE_CHECKING extern u8 journal_enable_debug; -#define jbd_debug(n, f, a...) \ - do { \ - if ((n) <= journal_enable_debug) { \ - printk (KERN_DEBUG "(%s, %d): %s: ", \ - __FILE__, __LINE__, __func__); \ - printk (f, ## a); \ - } \ - } while (0) +void __jbd_debug(int level, const char *file, const char *func, + unsigned int line, const char *fmt, ...); + +#define jbd_debug(n, fmt, a...) \ + __jbd_debug((n), __FILE__, __func__, __LINE__, (fmt), ##a) #else -#define jbd_debug(f, a...) /**/ +#define jbd_debug(n, fmt, a...) /**/ #endif static inline void *jbd_alloc(size_t size, gfp_t flags) @@ -78,7 +74,7 @@ static inline void *jbd_alloc(size_t size, gfp_t flags) static inline void jbd_free(void *ptr, size_t size) { free_pages((unsigned long)ptr, get_order(size)); -}; +} #define JFS_MIN_JOURNAL_BLOCKS 1024 @@ -244,6 +240,31 @@ typedef struct journal_superblock_s #include <linux/fs.h> #include <linux/sched.h> + +enum jbd_state_bits { + BH_JBD /* Has an attached ext3 journal_head */ + = BH_PrivateStart, + BH_JWrite, /* Being written to log (@@@ DEBUGGING) */ + BH_Freed, /* Has been freed (truncated) */ + BH_Revoked, /* Has been revoked from the log */ + BH_RevokeValid, /* Revoked flag is valid */ + BH_JBDDirty, /* Is dirty but journaled */ + BH_State, /* Pins most journal_head state */ + BH_JournalHead, /* Pins bh->b_private and jh->b_bh */ + BH_Unshadow, /* Dummy bit, for BJ_Shadow wakeup filtering */ + BH_JBDPrivateStart, /* First bit available for private use by FS */ +}; + +BUFFER_FNS(JBD, jbd) +BUFFER_FNS(JWrite, jwrite) +BUFFER_FNS(JBDDirty, jbddirty) +TAS_BUFFER_FNS(JBDDirty, jbddirty) +BUFFER_FNS(Revoked, revoked) +TAS_BUFFER_FNS(Revoked, revoked) +BUFFER_FNS(RevokeValid, revokevalid) +TAS_BUFFER_FNS(RevokeValid, revokevalid) +BUFFER_FNS(Freed, freed) + #include <linux/jbd_common.h> #define J_ASSERT(assert) BUG_ON(!(assert)) @@ -840,7 +861,7 @@ extern void journal_release_buffer (handle_t *, struct buffer_head *); extern int journal_forget (handle_t *, struct buffer_head *); extern void journal_sync_buffer (struct buffer_head *); extern void journal_invalidatepage(journal_t *, - struct page *, unsigned long); + struct page *, unsigned int, unsigned int); extern int journal_try_to_free_buffers(journal_t *, struct page *, gfp_t); extern int journal_stop(handle_t *); extern int journal_flush (journal_t *); @@ -887,7 +908,7 @@ extern struct kmem_cache *jbd_handle_cache; static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags) { - return kmem_cache_alloc(jbd_handle_cache, gfp_flags); + return kmem_cache_zalloc(jbd_handle_cache, gfp_flags); } static inline void jbd_free_handle(handle_t *handle) diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 50e5a5e6a712..d5b50a19463c 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -26,7 +26,6 @@ #include <linux/buffer_head.h> #include <linux/journal-head.h> #include <linux/stddef.h> -#include <linux/bit_spinlock.h> #include <linux/mutex.h> #include <linux/timer.h> #include <linux/slab.h> @@ -57,17 +56,13 @@ */ #define JBD2_EXPENSIVE_CHECKING extern ushort jbd2_journal_enable_debug; +void __jbd2_debug(int level, const char *file, const char *func, + unsigned int line, const char *fmt, ...); -#define jbd_debug(n, f, a...) \ - do { \ - if ((n) <= jbd2_journal_enable_debug) { \ - printk (KERN_DEBUG "(%s, %d): %s: ", \ - __FILE__, __LINE__, __func__); \ - printk (f, ## a); \ - } \ - } while (0) +#define jbd_debug(n, fmt, a...) \ + __jbd2_debug((n), __FILE__, __func__, __LINE__, (fmt), ##a) #else -#define jbd_debug(f, a...) /**/ +#define jbd_debug(n, fmt, a...) /**/ #endif extern void *jbd2_alloc(size_t size, gfp_t flags); @@ -302,6 +297,34 @@ typedef struct journal_superblock_s #include <linux/fs.h> #include <linux/sched.h> + +enum jbd_state_bits { + BH_JBD /* Has an attached ext3 journal_head */ + = BH_PrivateStart, + BH_JWrite, /* Being written to log (@@@ DEBUGGING) */ + BH_Freed, /* Has been freed (truncated) */ + BH_Revoked, /* Has been revoked from the log */ + BH_RevokeValid, /* Revoked flag is valid */ + BH_JBDDirty, /* Is dirty but journaled */ + BH_State, /* Pins most journal_head state */ + BH_JournalHead, /* Pins bh->b_private and jh->b_bh */ + BH_Shadow, /* IO on shadow buffer is running */ + BH_Verified, /* Metadata block has been verified ok */ + BH_JBDPrivateStart, /* First bit available for private use by FS */ +}; + +BUFFER_FNS(JBD, jbd) +BUFFER_FNS(JWrite, jwrite) +BUFFER_FNS(JBDDirty, jbddirty) +TAS_BUFFER_FNS(JBDDirty, jbddirty) +BUFFER_FNS(Revoked, revoked) +TAS_BUFFER_FNS(Revoked, revoked) +BUFFER_FNS(RevokeValid, revokevalid) +TAS_BUFFER_FNS(RevokeValid, revokevalid) +BUFFER_FNS(Freed, freed) +BUFFER_FNS(Shadow, shadow) +BUFFER_FNS(Verified, verified) + #include <linux/jbd_common.h> #define J_ASSERT(assert) BUG_ON(!(assert)) @@ -382,8 +405,15 @@ struct jbd2_revoke_table_s; struct jbd2_journal_handle { - /* Which compound transaction is this update a part of? */ - transaction_t *h_transaction; + union { + /* Which compound transaction is this update a part of? */ + transaction_t *h_transaction; + /* Which journal handle belongs to - used iff h_reserved set */ + journal_t *h_journal; + }; + + /* Handle reserved for finishing the logical operation */ + handle_t *h_rsv_handle; /* Number of remaining buffers we are allowed to dirty: */ int h_buffer_credits; @@ -398,6 +428,7 @@ struct jbd2_journal_handle /* Flags [no locking] */ unsigned int h_sync: 1; /* sync-on-close */ unsigned int h_jdata: 1; /* force data journaling */ + unsigned int h_reserved: 1; /* handle with reserved credits */ unsigned int h_aborted: 1; /* fatal error on handle */ unsigned int h_type: 8; /* for handle statistics */ unsigned int h_line_no: 16; /* for handle statistics */ @@ -480,6 +511,7 @@ struct transaction_s T_COMMIT, T_COMMIT_DFLUSH, T_COMMIT_JFLUSH, + T_COMMIT_CALLBACK, T_FINISHED } t_state; @@ -523,12 +555,6 @@ struct transaction_s struct journal_head *t_checkpoint_io_list; /* - * Doubly-linked circular list of temporary buffers currently undergoing - * IO in the log [j_list_lock] - */ - struct journal_head *t_iobuf_list; - - /* * Doubly-linked circular list of metadata buffers being shadowed by log * IO. The IO buffers on the iobuf list and the shadow buffers on this * list match each other one for one at all times. [j_list_lock] @@ -536,12 +562,6 @@ struct transaction_s struct journal_head *t_shadow_list; /* - * Doubly-linked circular list of control buffers being written to the - * log. [j_list_lock] - */ - struct journal_head *t_log_list; - - /* * List of inodes whose data we've modified in data=ordered mode. * [j_list_lock] */ @@ -670,11 +690,10 @@ jbd2_time_diff(unsigned long start, unsigned long end) * waiting for checkpointing * @j_wait_transaction_locked: Wait queue for waiting for a locked transaction * to start committing, or for a barrier lock to be released - * @j_wait_logspace: Wait queue for waiting for checkpointing to complete * @j_wait_done_commit: Wait queue for waiting for commit to complete - * @j_wait_checkpoint: Wait queue to trigger checkpointing * @j_wait_commit: Wait queue to trigger commit * @j_wait_updates: Wait queue to wait for updates to complete + * @j_wait_reserved: Wait queue to wait for reserved buffer credits to drop * @j_checkpoint_mutex: Mutex for locking against concurrent checkpoints * @j_head: Journal head - identifies the first unused block in the journal * @j_tail: Journal tail - identifies the oldest still-used block in the @@ -688,6 +707,7 @@ jbd2_time_diff(unsigned long start, unsigned long end) * journal * @j_fs_dev: Device which holds the client fs. For internal journal this will * be equal to j_dev + * @j_reserved_credits: Number of buffers reserved from the running transaction * @j_maxlen: Total maximum capacity of the journal region on disk. * @j_list_lock: Protects the buffer lists and internal buffer state. * @j_inode: Optional inode where we store the journal. If present, all journal @@ -777,21 +797,18 @@ struct journal_s */ wait_queue_head_t j_wait_transaction_locked; - /* Wait queue for waiting for checkpointing to complete */ - wait_queue_head_t j_wait_logspace; - /* Wait queue for waiting for commit to complete */ wait_queue_head_t j_wait_done_commit; - /* Wait queue to trigger checkpointing */ - wait_queue_head_t j_wait_checkpoint; - /* Wait queue to trigger commit */ wait_queue_head_t j_wait_commit; /* Wait queue to wait for updates to complete */ wait_queue_head_t j_wait_updates; + /* Wait queue to wait for reserved buffer credits to drop */ + wait_queue_head_t j_wait_reserved; + /* Semaphore for locking against concurrent checkpoints */ struct mutex j_checkpoint_mutex; @@ -846,6 +863,9 @@ struct journal_s /* Total maximum capacity of the journal region on disk. */ unsigned int j_maxlen; + /* Number of buffers reserved from the running transaction */ + atomic_t j_reserved_credits; + /* * Protects the buffer lists and internal buffer state. */ @@ -990,9 +1010,17 @@ extern void __jbd2_journal_file_buffer(struct journal_head *, transaction_t *, i extern void __journal_free_buffer(struct journal_head *bh); extern void jbd2_journal_file_buffer(struct journal_head *, transaction_t *, int); extern void __journal_clean_data_list(transaction_t *transaction); +static inline void jbd2_file_log_bh(struct list_head *head, struct buffer_head *bh) +{ + list_add_tail(&bh->b_assoc_buffers, head); +} +static inline void jbd2_unfile_log_bh(struct buffer_head *bh) +{ + list_del_init(&bh->b_assoc_buffers); +} /* Log buffer allocation */ -extern struct journal_head * jbd2_journal_get_descriptor_buffer(journal_t *); +struct buffer_head *jbd2_journal_get_descriptor_buffer(journal_t *journal); int jbd2_journal_next_log_block(journal_t *, unsigned long long *); int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid, unsigned long *block); @@ -1038,11 +1066,10 @@ extern void jbd2_buffer_abort_trigger(struct journal_head *jh, struct jbd2_buffer_trigger_type *triggers); /* Buffer IO */ -extern int -jbd2_journal_write_metadata_buffer(transaction_t *transaction, - struct journal_head *jh_in, - struct journal_head **jh_out, - unsigned long long blocknr); +extern int jbd2_journal_write_metadata_buffer(transaction_t *transaction, + struct journal_head *jh_in, + struct buffer_head **bh_out, + sector_t blocknr); /* Transaction locking */ extern void __wait_on_journal (journal_t *); @@ -1075,10 +1102,14 @@ static inline handle_t *journal_current_handle(void) */ extern handle_t *jbd2_journal_start(journal_t *, int nblocks); -extern handle_t *jbd2__journal_start(journal_t *, int nblocks, gfp_t gfp_mask, - unsigned int type, unsigned int line_no); +extern handle_t *jbd2__journal_start(journal_t *, int blocks, int rsv_blocks, + gfp_t gfp_mask, unsigned int type, + unsigned int line_no); extern int jbd2_journal_restart(handle_t *, int nblocks); extern int jbd2__journal_restart(handle_t *, int nblocks, gfp_t gfp_mask); +extern int jbd2_journal_start_reserved(handle_t *handle, + unsigned int type, unsigned int line_no); +extern void jbd2_journal_free_reserved(handle_t *handle); extern int jbd2_journal_extend (handle_t *, int nblocks); extern int jbd2_journal_get_write_access(handle_t *, struct buffer_head *); extern int jbd2_journal_get_create_access (handle_t *, struct buffer_head *); @@ -1089,7 +1120,7 @@ extern int jbd2_journal_dirty_metadata (handle_t *, struct buffer_head *); extern int jbd2_journal_forget (handle_t *, struct buffer_head *); extern void journal_sync_buffer (struct buffer_head *); extern int jbd2_journal_invalidatepage(journal_t *, - struct page *, unsigned long); + struct page *, unsigned int, unsigned int); extern int jbd2_journal_try_to_free_buffers(journal_t *, struct page *, gfp_t); extern int jbd2_journal_stop(handle_t *); extern int jbd2_journal_flush (journal_t *); @@ -1124,6 +1155,7 @@ extern void jbd2_journal_ack_err (journal_t *); extern int jbd2_journal_clear_err (journal_t *); extern int jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *); extern int jbd2_journal_force_commit(journal_t *); +extern int jbd2_journal_force_commit_nested(journal_t *); extern int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode); extern int jbd2_journal_begin_ordered_truncate(journal_t *journal, struct jbd2_inode *inode, loff_t new_size); @@ -1144,7 +1176,7 @@ extern struct kmem_cache *jbd2_handle_cache; static inline handle_t *jbd2_alloc_handle(gfp_t gfp_flags) { - return kmem_cache_alloc(jbd2_handle_cache, gfp_flags); + return kmem_cache_zalloc(jbd2_handle_cache, gfp_flags); } static inline void jbd2_free_handle(handle_t *handle) @@ -1177,8 +1209,10 @@ extern int jbd2_journal_init_revoke_caches(void); extern void jbd2_journal_destroy_revoke(journal_t *); extern int jbd2_journal_revoke (handle_t *, unsigned long long, struct buffer_head *); extern int jbd2_journal_cancel_revoke(handle_t *, struct journal_head *); -extern void jbd2_journal_write_revoke_records(journal_t *, - transaction_t *, int); +extern void jbd2_journal_write_revoke_records(journal_t *journal, + transaction_t *transaction, + struct list_head *log_bufs, + int write_op); /* Recovery revoke support */ extern int jbd2_journal_set_revoke(journal_t *, unsigned long long, tid_t); @@ -1194,12 +1228,11 @@ extern void jbd2_clear_buffer_revoked_flags(journal_t *journal); * transitions on demand. */ -int __jbd2_log_space_left(journal_t *); /* Called with journal locked */ int jbd2_log_start_commit(journal_t *journal, tid_t tid); int __jbd2_log_start_commit(journal_t *journal, tid_t tid); int jbd2_journal_start_commit(journal_t *journal, tid_t *tid); -int jbd2_journal_force_commit_nested(journal_t *journal); int jbd2_log_wait_commit(journal_t *journal, tid_t tid); +int jbd2_complete_transaction(journal_t *journal, tid_t tid); int jbd2_log_do_checkpoint(journal_t *journal); int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid); @@ -1233,7 +1266,7 @@ static inline int is_journal_aborted(journal_t *journal) static inline int is_handle_aborted(handle_t *handle) { - if (handle->h_aborted) + if (handle->h_aborted || !handle->h_transaction) return 1; return is_journal_aborted(handle->h_transaction->t_journal); } @@ -1264,16 +1297,37 @@ extern int jbd2_journal_blocks_per_page(struct inode *inode); extern size_t journal_tag_bytes(journal_t *journal); /* + * We reserve t_outstanding_credits >> JBD2_CONTROL_BLOCKS_SHIFT for + * transaction control blocks. + */ +#define JBD2_CONTROL_BLOCKS_SHIFT 5 + +/* * Return the minimum number of blocks which must be free in the journal * before a new transaction may be started. Must be called under j_state_lock. */ -static inline int jbd_space_needed(journal_t *journal) +static inline int jbd2_space_needed(journal_t *journal) { int nblocks = journal->j_max_transaction_buffers; - if (journal->j_committing_transaction) - nblocks += atomic_read(&journal->j_committing_transaction-> - t_outstanding_credits); - return nblocks; + return nblocks + (nblocks >> JBD2_CONTROL_BLOCKS_SHIFT); +} + +/* + * Return number of free blocks in the log. Must be called under j_state_lock. + */ +static inline unsigned long jbd2_log_space_left(journal_t *journal) +{ + /* Allow for rounding errors */ + unsigned long free = journal->j_free - 32; + + if (journal->j_committing_transaction) { + unsigned long committing = atomic_read(&journal-> + j_committing_transaction->t_outstanding_credits); + + /* Transaction + control blocks */ + free -= committing + (committing >> JBD2_CONTROL_BLOCKS_SHIFT); + } + return free; } /* @@ -1284,11 +1338,9 @@ static inline int jbd_space_needed(journal_t *journal) #define BJ_None 0 /* Not journaled */ #define BJ_Metadata 1 /* Normal journaled metadata */ #define BJ_Forget 2 /* Buffer superseded by this transaction */ -#define BJ_IO 3 /* Buffer is for temporary IO use */ -#define BJ_Shadow 4 /* Buffer contents being shadowed to the log */ -#define BJ_LogCtl 5 /* Buffer contains log descriptors */ -#define BJ_Reserved 6 /* Buffer is reserved for access by journal */ -#define BJ_Types 7 +#define BJ_Shadow 3 /* Buffer contents being shadowed to the log */ +#define BJ_Reserved 4 /* Buffer is reserved for access by journal */ +#define BJ_Types 5 extern int jbd_blocks_per_page(struct inode *inode); @@ -1317,6 +1369,19 @@ static inline u32 jbd2_chksum(journal_t *journal, u32 crc, return *(u32 *)desc.ctx; } +/* Return most recent uncommitted transaction */ +static inline tid_t jbd2_get_latest_transaction(journal_t *journal) +{ + tid_t tid; + + read_lock(&journal->j_state_lock); + tid = journal->j_commit_request; + if (journal->j_running_transaction) + tid = journal->j_running_transaction->t_tid; + read_unlock(&journal->j_state_lock); + return tid; +} + #ifdef __KERNEL__ #define buffer_trace_init(bh) do {} while (0) diff --git a/include/linux/jbd_common.h b/include/linux/jbd_common.h index 6133679bc4c0..3dc53432355f 100644 --- a/include/linux/jbd_common.h +++ b/include/linux/jbd_common.h @@ -1,31 +1,7 @@ #ifndef _LINUX_JBD_STATE_H #define _LINUX_JBD_STATE_H -enum jbd_state_bits { - BH_JBD /* Has an attached ext3 journal_head */ - = BH_PrivateStart, - BH_JWrite, /* Being written to log (@@@ DEBUGGING) */ - BH_Freed, /* Has been freed (truncated) */ - BH_Revoked, /* Has been revoked from the log */ - BH_RevokeValid, /* Revoked flag is valid */ - BH_JBDDirty, /* Is dirty but journaled */ - BH_State, /* Pins most journal_head state */ - BH_JournalHead, /* Pins bh->b_private and jh->b_bh */ - BH_Unshadow, /* Dummy bit, for BJ_Shadow wakeup filtering */ - BH_Verified, /* Metadata block has been verified ok */ - BH_JBDPrivateStart, /* First bit available for private use by FS */ -}; - -BUFFER_FNS(JBD, jbd) -BUFFER_FNS(JWrite, jwrite) -BUFFER_FNS(JBDDirty, jbddirty) -TAS_BUFFER_FNS(JBDDirty, jbddirty) -BUFFER_FNS(Revoked, revoked) -TAS_BUFFER_FNS(Revoked, revoked) -BUFFER_FNS(RevokeValid, revokevalid) -TAS_BUFFER_FNS(RevokeValid, revokevalid) -BUFFER_FNS(Freed, freed) -BUFFER_FNS(Verified, verified) +#include <linux/bit_spinlock.h> static inline struct buffer_head *jh2bh(struct journal_head *jh) { diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index 82ed068b1ebe..d235e88cfd7c 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h @@ -75,7 +75,6 @@ extern int register_refined_jiffies(long clock_tick_rate); */ extern u64 __jiffy_data jiffies_64; extern unsigned long volatile __jiffy_data jiffies; -extern seqlock_t jiffies_lock; #if (BITS_PER_LONG < 64) u64 get_jiffies_64(void); @@ -102,13 +101,13 @@ static inline u64 get_jiffies_64(void) #define time_after(a,b) \ (typecheck(unsigned long, a) && \ typecheck(unsigned long, b) && \ - ((long)(b) - (long)(a) < 0)) + ((long)((b) - (a)) < 0)) #define time_before(a,b) time_after(b,a) #define time_after_eq(a,b) \ (typecheck(unsigned long, a) && \ typecheck(unsigned long, b) && \ - ((long)(a) - (long)(b) >= 0)) + ((long)((a) - (b)) >= 0)) #define time_before_eq(a,b) time_after_eq(b,a) /* @@ -131,15 +130,19 @@ static inline u64 get_jiffies_64(void) #define time_after64(a,b) \ (typecheck(__u64, a) && \ typecheck(__u64, b) && \ - ((__s64)(b) - (__s64)(a) < 0)) + ((__s64)((b) - (a)) < 0)) #define time_before64(a,b) time_after64(b,a) #define time_after_eq64(a,b) \ (typecheck(__u64, a) && \ typecheck(__u64, b) && \ - ((__s64)(a) - (__s64)(b) >= 0)) + ((__s64)((a) - (b)) >= 0)) #define time_before_eq64(a,b) time_after_eq64(b,a) +#define time_in_range64(a, b, c) \ + (time_after_eq64(a, b) && \ + time_before_eq64(a, c)) + /* * These four macros compare jiffies and 'a' for convenience. */ diff --git a/include/linux/journal-head.h b/include/linux/journal-head.h index c18b46f8aeeb..98cd41bb39c8 100644 --- a/include/linux/journal-head.h +++ b/include/linux/journal-head.h @@ -30,6 +30,10 @@ struct journal_head { /* * Journalling list for this buffer [jbd_lock_bh_state()] + * NOTE: We *cannot* combine this with b_modified into a bitfield + * as gcc would then (which the C standard allows but which is + * very unuseful) make 64-bit accesses to the bitfield and clobber + * b_jcount if its update races with bitfield modification. */ unsigned b_jlist; @@ -41,13 +45,6 @@ struct journal_head { unsigned b_modified; /* - * This feild tracks the last transaction id in which this buffer - * has been cowed - * [jbd_lock_bh_state()] - */ - tid_t b_cow_tid; - - /* * Copy of the buffer data frozen for writing to the log. * [jbd_lock_bh_state()] */ diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index 0976fc46d1e0..a5079072da66 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h @@ -48,7 +48,6 @@ #include <linux/types.h> #include <linux/compiler.h> -#include <linux/workqueue.h> #if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL) @@ -61,12 +60,6 @@ struct static_key { #endif }; -struct static_key_deferred { - struct static_key key; - unsigned long timeout; - struct delayed_work work; -}; - # include <asm/jump_label.h> # define HAVE_JUMP_LABEL #endif /* CC_HAVE_ASM_GOTO && CONFIG_JUMP_LABEL */ @@ -78,6 +71,7 @@ enum jump_label_type { struct module; +#include <linux/atomic.h> #ifdef HAVE_JUMP_LABEL #define JUMP_LABEL_TRUE_BRANCH 1UL @@ -119,10 +113,7 @@ extern void arch_jump_label_transform_static(struct jump_entry *entry, extern int jump_label_text_reserved(void *start, void *end); extern void static_key_slow_inc(struct static_key *key); extern void static_key_slow_dec(struct static_key *key); -extern void static_key_slow_dec_deferred(struct static_key_deferred *key); extern void jump_label_apply_nops(struct module *mod); -extern void -jump_label_rate_limit(struct static_key_deferred *key, unsigned long rl); #define STATIC_KEY_INIT_TRUE ((struct static_key) \ { .enabled = ATOMIC_INIT(1), .entries = (void *)1 }) @@ -131,8 +122,6 @@ jump_label_rate_limit(struct static_key_deferred *key, unsigned long rl); #else /* !HAVE_JUMP_LABEL */ -#include <linux/atomic.h> - struct static_key { atomic_t enabled; }; @@ -141,10 +130,6 @@ static __always_inline void jump_label_init(void) { } -struct static_key_deferred { - struct static_key key; -}; - static __always_inline bool static_key_false(struct static_key *key) { if (unlikely(atomic_read(&key->enabled)) > 0) @@ -169,11 +154,6 @@ static inline void static_key_slow_dec(struct static_key *key) atomic_dec(&key->enabled); } -static inline void static_key_slow_dec_deferred(struct static_key_deferred *key) -{ - static_key_slow_dec(&key->key); -} - static inline int jump_label_text_reserved(void *start, void *end) { return 0; @@ -187,12 +167,6 @@ static inline int jump_label_apply_nops(struct module *mod) return 0; } -static inline void -jump_label_rate_limit(struct static_key_deferred *key, - unsigned long rl) -{ -} - #define STATIC_KEY_INIT_TRUE ((struct static_key) \ { .enabled = ATOMIC_INIT(1) }) #define STATIC_KEY_INIT_FALSE ((struct static_key) \ diff --git a/include/linux/jump_label_ratelimit.h b/include/linux/jump_label_ratelimit.h new file mode 100644 index 000000000000..113788389b3d --- /dev/null +++ b/include/linux/jump_label_ratelimit.h @@ -0,0 +1,34 @@ +#ifndef _LINUX_JUMP_LABEL_RATELIMIT_H +#define _LINUX_JUMP_LABEL_RATELIMIT_H + +#include <linux/jump_label.h> +#include <linux/workqueue.h> + +#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL) +struct static_key_deferred { + struct static_key key; + unsigned long timeout; + struct delayed_work work; +}; +#endif + +#ifdef HAVE_JUMP_LABEL +extern void static_key_slow_dec_deferred(struct static_key_deferred *key); +extern void +jump_label_rate_limit(struct static_key_deferred *key, unsigned long rl); + +#else /* !HAVE_JUMP_LABEL */ +struct static_key_deferred { + struct static_key key; +}; +static inline void static_key_slow_dec_deferred(struct static_key_deferred *key) +{ + static_key_slow_dec(&key->key); +} +static inline void +jump_label_rate_limit(struct static_key_deferred *key, + unsigned long rl) +{ +} +#endif /* HAVE_JUMP_LABEL */ +#endif /* _LINUX_JUMP_LABEL_RATELIMIT_H */ diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index b7c8cdc1d422..cbfb171bbcba 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h @@ -36,10 +36,9 @@ struct kbd_struct { #define VC_CTRLRLOCK KG_CTRLR /* ctrlr lock mode */ unsigned char slockstate; /* for `sticky' Shift, Ctrl, etc. */ - unsigned char ledmode:2; /* one 2-bit value */ + unsigned char ledmode:1; #define LED_SHOW_FLAGS 0 /* traditional state */ #define LED_SHOW_IOCTL 1 /* only change leds upon ioctl */ -#define LED_SHOW_MEM 2 /* `heartbeat': peek into memory */ unsigned char ledflagstate:4; /* flags, not lights */ unsigned char default_ledflagstate:4; diff --git a/include/linux/kcore.h b/include/linux/kcore.h new file mode 100644 index 000000000000..d92762286645 --- /dev/null +++ b/include/linux/kcore.h @@ -0,0 +1,38 @@ +/* + * /proc/kcore definitions + */ +#ifndef _LINUX_KCORE_H +#define _LINUX_KCORE_H + +enum kcore_type { + KCORE_TEXT, + KCORE_VMALLOC, + KCORE_RAM, + KCORE_VMEMMAP, + KCORE_OTHER, +}; + +struct kcore_list { + struct list_head list; + unsigned long addr; + size_t size; + int type; +}; + +struct vmcore { + struct list_head list; + unsigned long long paddr; + unsigned long long size; + loff_t offset; +}; + +#ifdef CONFIG_PROC_KCORE +extern void kclist_add(struct kcore_list *, void *, size_t, int type); +#else +static inline +void kclist_add(struct kcore_list *new, void *addr, size_t size, int type) +{ +} +#endif + +#endif /* _LINUX_KCORE_H */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 80d36874689b..672ddc4de4af 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -193,13 +193,10 @@ extern int _cond_resched(void); (__x < 0) ? -__x : __x; \ }) -#ifdef CONFIG_PROVE_LOCKING +#if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_DEBUG_ATOMIC_SLEEP) void might_fault(void); #else -static inline void might_fault(void) -{ - might_sleep(); -} +static inline void might_fault(void) { } #endif extern struct atomic_notifier_head panic_notifier_list; @@ -390,7 +387,6 @@ extern struct pid *session_of_pgrp(struct pid *pgrp); unsigned long int_sqrt(unsigned long); extern void bust_spinlocks(int yes); -extern void wake_up_klogd(void); extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */ extern int panic_timeout; extern int panic_on_oops; @@ -443,6 +439,17 @@ static inline char *hex_byte_pack(char *buf, u8 byte) return buf; } +extern const char hex_asc_upper[]; +#define hex_asc_upper_lo(x) hex_asc_upper[((x) & 0x0f)] +#define hex_asc_upper_hi(x) hex_asc_upper[((x) & 0xf0) >> 4] + +static inline char *hex_byte_pack_upper(char *buf, u8 byte) +{ + *buf++ = hex_asc_upper_hi(byte); + *buf++ = hex_asc_upper_lo(byte); + return buf; +} + static inline char * __deprecated pack_hex_byte(char *buf, u8 byte) { return hex_byte_pack(buf, byte); @@ -451,6 +458,8 @@ static inline char * __deprecated pack_hex_byte(char *buf, u8 byte) extern int hex_to_bin(char ch); extern int __must_check hex2bin(u8 *dst, const char *src, size_t count); +int mac_pton(const char *s, u8 *mac); + /* * General tracing related utility functions - trace_printk(), * tracing_on/tracing_off and tracing_start()/tracing_stop @@ -487,6 +496,8 @@ enum ftrace_dump_mode { void tracing_on(void); void tracing_off(void); int tracing_is_on(void); +void tracing_snapshot(void); +void tracing_snapshot_alloc(void); extern void tracing_start(void); extern void tracing_stop(void); @@ -516,10 +527,32 @@ do { \ * * This is intended as a debugging tool for the developer only. * Please refrain from leaving trace_printks scattered around in - * your code. + * your code. (Extra memory is used for special buffers that are + * allocated when trace_printk() is used) + * + * A little optization trick is done here. If there's only one + * argument, there's no need to scan the string for printf formats. + * The trace_puts() will suffice. But how can we take advantage of + * using trace_puts() when trace_printk() has only one argument? + * By stringifying the args and checking the size we can tell + * whether or not there are args. __stringify((__VA_ARGS__)) will + * turn into "()\0" with a size of 3 when there are no args, anything + * else will be bigger. All we need to do is define a string to this, + * and then take its size and compare to 3. If it's bigger, use + * do_trace_printk() otherwise, optimize it to trace_puts(). Then just + * let gcc optimize the rest. */ -#define trace_printk(fmt, args...) \ +#define trace_printk(fmt, ...) \ +do { \ + char _______STR[] = __stringify((__VA_ARGS__)); \ + if (sizeof(_______STR) > 3) \ + do_trace_printk(fmt, ##__VA_ARGS__); \ + else \ + trace_puts(fmt); \ +} while (0) + +#define do_trace_printk(fmt, args...) \ do { \ static const char *trace_printk_fmt \ __attribute__((section("__trace_printk_fmt"))) = \ @@ -539,7 +572,45 @@ int __trace_bprintk(unsigned long ip, const char *fmt, ...); extern __printf(2, 3) int __trace_printk(unsigned long ip, const char *fmt, ...); -extern void trace_dump_stack(void); +/** + * trace_puts - write a string into the ftrace buffer + * @str: the string to record + * + * Note: __trace_bputs is an internal function for trace_puts and + * the @ip is passed in via the trace_puts macro. + * + * This is similar to trace_printk() but is made for those really fast + * paths that a developer wants the least amount of "Heisenbug" affects, + * where the processing of the print format is still too much. + * + * This function allows a kernel developer to debug fast path sections + * that printk is not appropriate for. By scattering in various + * printk like tracing in the code, a developer can quickly see + * where problems are occurring. + * + * This is intended as a debugging tool for the developer only. + * Please refrain from leaving trace_puts scattered around in + * your code. (Extra memory is used for special buffers that are + * allocated when trace_puts() is used) + * + * Returns: 0 if nothing was written, positive # if string was. + * (1 when __trace_bputs is used, strlen(str) when __trace_puts is used) + */ + +#define trace_puts(str) ({ \ + static const char *trace_printk_fmt \ + __attribute__((section("__trace_printk_fmt"))) = \ + __builtin_constant_p(str) ? str : NULL; \ + \ + if (__builtin_constant_p(str)) \ + __trace_bputs(_THIS_IP_, trace_printk_fmt); \ + else \ + __trace_puts(_THIS_IP_, str, strlen(str)); \ +}) +extern int __trace_bputs(unsigned long ip, const char *str); +extern int __trace_puts(unsigned long ip, const char *str, int size); + +extern void trace_dump_stack(int skip); /* * The double __builtin_constant_p is because gcc will give us an error @@ -569,11 +640,13 @@ extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode); static inline void tracing_start(void) { } static inline void tracing_stop(void) { } static inline void ftrace_off_permanent(void) { } -static inline void trace_dump_stack(void) { } +static inline void trace_dump_stack(int skip) { } static inline void tracing_on(void) { } static inline void tracing_off(void) { } static inline int tracing_is_on(void) { return 0; } +static inline void tracing_snapshot(void) { } +static inline void tracing_snapshot_alloc(void) { } static inline __printf(1, 2) int trace_printk(const char *fmt, ...) @@ -723,18 +796,9 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } /* Trap pasters of __FUNCTION__ at compile-time */ #define __FUNCTION__ (__func__) -/* This helps us to avoid #ifdef CONFIG_SYMBOL_PREFIX */ -#ifdef CONFIG_SYMBOL_PREFIX -#define SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX -#else -#define SYMBOL_PREFIX "" -#endif - /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ #ifdef CONFIG_FTRACE_MCOUNT_RECORD # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD #endif -extern int do_sysinfo(struct sysinfo *info); - #endif diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index ed5f6ed6eb77..51c72be4a7c3 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -36,9 +36,6 @@ struct kernel_cpustat { }; struct kernel_stat { -#ifndef CONFIG_GENERIC_HARDIRQS - unsigned int irqs[NR_IRQS]; -#endif unsigned long irqs_sum; unsigned int softirqs[NR_SOFTIRQS]; }; @@ -54,22 +51,6 @@ DECLARE_PER_CPU(struct kernel_cpustat, kernel_cpustat); extern unsigned long long nr_context_switches(void); -#ifndef CONFIG_GENERIC_HARDIRQS - -struct irq_desc; - -static inline void kstat_incr_irqs_this_cpu(unsigned int irq, - struct irq_desc *desc) -{ - __this_cpu_inc(kstat.irqs[irq]); - __this_cpu_inc(kstat.irqs_sum); -} - -static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) -{ - return kstat_cpu(cpu).irqs[irq]; -} -#else #include <linux/irq.h> extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu); @@ -79,8 +60,6 @@ do { \ __this_cpu_inc(kstat.irqs_sum); \ } while (0) -#endif - static inline void kstat_incr_softirqs_this_cpu(unsigned int irq) { __this_cpu_inc(kstat.softirqs[irq]); @@ -94,20 +73,7 @@ static inline unsigned int kstat_softirqs_cpu(unsigned int irq, int cpu) /* * Number of interrupts per specific IRQ source, since bootup */ -#ifndef CONFIG_GENERIC_HARDIRQS -static inline unsigned int kstat_irqs(unsigned int irq) -{ - unsigned int sum = 0; - int cpu; - - for_each_possible_cpu(cpu) - sum += kstat_irqs_cpu(irq, cpu); - - return sum; -} -#else extern unsigned int kstat_irqs(unsigned int irq); -#endif /* * Number of interrupts per cpu, since bootup diff --git a/include/linux/kexec.h b/include/linux/kexec.h index d2e6927bbaae..d78d28a733b1 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -200,6 +200,8 @@ extern size_t vmcoreinfo_max_size; int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base); +int parse_crashkernel_high(char *cmdline, unsigned long long system_ram, + unsigned long long *crash_size, unsigned long long *crash_base); int parse_crashkernel_low(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base); int crash_shrink_memory(unsigned long new_size); diff --git a/include/linux/kmalloc_sizes.h b/include/linux/kmalloc_sizes.h deleted file mode 100644 index e576b848ce10..000000000000 --- a/include/linux/kmalloc_sizes.h +++ /dev/null @@ -1,45 +0,0 @@ -#if (PAGE_SIZE == 4096) - CACHE(32) -#endif - CACHE(64) -#if L1_CACHE_BYTES < 64 - CACHE(96) -#endif - CACHE(128) -#if L1_CACHE_BYTES < 128 - CACHE(192) -#endif - CACHE(256) - CACHE(512) - CACHE(1024) - CACHE(2048) - CACHE(4096) - CACHE(8192) - CACHE(16384) - CACHE(32768) - CACHE(65536) - CACHE(131072) -#if KMALLOC_MAX_SIZE >= 262144 - CACHE(262144) -#endif -#if KMALLOC_MAX_SIZE >= 524288 - CACHE(524288) -#endif -#if KMALLOC_MAX_SIZE >= 1048576 - CACHE(1048576) -#endif -#if KMALLOC_MAX_SIZE >= 2097152 - CACHE(2097152) -#endif -#if KMALLOC_MAX_SIZE >= 4194304 - CACHE(4194304) -#endif -#if KMALLOC_MAX_SIZE >= 8388608 - CACHE(8388608) -#endif -#if KMALLOC_MAX_SIZE >= 16777216 - CACHE(16777216) -#endif -#if KMALLOC_MAX_SIZE >= 33554432 - CACHE(33554432) -#endif diff --git a/include/linux/kmod.h b/include/linux/kmod.h index 5398d5807075..0555cc66a15b 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -67,16 +67,15 @@ struct subprocess_info { }; extern int -call_usermodehelper_fns(char *path, char **argv, char **envp, int wait, - int (*init)(struct subprocess_info *info, struct cred *new), - void (*cleanup)(struct subprocess_info *), void *data); +call_usermodehelper(char *path, char **argv, char **envp, int wait); -static inline int -call_usermodehelper(char *path, char **argv, char **envp, int wait) -{ - return call_usermodehelper_fns(path, argv, envp, wait, - NULL, NULL, NULL); -} +extern struct subprocess_info * +call_usermodehelper_setup(char *path, char **argv, char **envp, gfp_t gfp_mask, + int (*init)(struct subprocess_info *info, struct cred *new), + void (*cleanup)(struct subprocess_info *), void *data); + +extern int +call_usermodehelper_exec(struct subprocess_info *info, int wait); extern struct ctl_table usermodehelper_table[]; diff --git a/include/linux/kobj_completion.h b/include/linux/kobj_completion.h new file mode 100644 index 000000000000..a428f6436063 --- /dev/null +++ b/include/linux/kobj_completion.h @@ -0,0 +1,18 @@ +#ifndef _KOBJ_COMPLETION_H_ +#define _KOBJ_COMPLETION_H_ + +#include <linux/kobject.h> +#include <linux/completion.h> + +struct kobj_completion { + struct kobject kc_kobj; + struct completion kc_unregister; +}; + +#define kobj_to_kobj_completion(kobj) \ + container_of(kobj, struct kobj_completion, kc_kobj) + +void kobj_completion_init(struct kobj_completion *kc, struct kobj_type *ktype); +void kobj_completion_release(struct kobject *kobj); +void kobj_completion_del_and_wait(struct kobj_completion *kc); +#endif /* _KOBJ_COMPLETION_H_ */ diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 939b11268c86..e7ba650086ce 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -26,6 +26,7 @@ #include <linux/kernel.h> #include <linux/wait.h> #include <linux/atomic.h> +#include <linux/workqueue.h> #define UEVENT_HELPER_PATH_LEN 256 #define UEVENT_NUM_ENVP 32 /* number of env pointers */ @@ -65,6 +66,9 @@ struct kobject { struct kobj_type *ktype; struct sysfs_dirent *sd; struct kref kref; +#ifdef CONFIG_DEBUG_KOBJECT_RELEASE + struct delayed_work release; +#endif unsigned int state_initialized:1; unsigned int state_in_sysfs:1; unsigned int state_add_uevent_sent:1; @@ -103,6 +107,7 @@ extern int __must_check kobject_move(struct kobject *, struct kobject *); extern struct kobject *kobject_get(struct kobject *kobj); extern void kobject_put(struct kobject *kobj); +extern const void *kobject_namespace(struct kobject *kobj); extern char *kobject_get_path(struct kobject *kobj, gfp_t flag); struct kobj_type { diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h index f66b065a8b5f..df32d2508290 100644 --- a/include/linux/kobject_ns.h +++ b/include/linux/kobject_ns.h @@ -39,6 +39,7 @@ enum kobj_ns_type { */ struct kobj_ns_type_operations { enum kobj_ns_type type; + bool (*current_may_mount)(void); void *(*grab_current_ns)(void); const void *(*netlink_ns)(struct sock *sk); const void *(*initial_ns)(void); @@ -50,6 +51,7 @@ int kobj_ns_type_registered(enum kobj_ns_type type); const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent); const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj); +bool kobj_ns_current_may_mount(enum kobj_ns_type type); void *kobj_ns_grab_current(enum kobj_ns_type type); const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk); const void *kobj_ns_initial(enum kobj_ns_type type); diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 4b6ef4d33cc2..925eaf28fca9 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -29,6 +29,7 @@ * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi * <prasanna@in.ibm.com> added function-return probes. */ +#include <linux/compiler.h> /* for __kprobes */ #include <linux/linkage.h> #include <linux/list.h> #include <linux/notifier.h> @@ -49,16 +50,11 @@ #define KPROBE_REENTER 0x00000004 #define KPROBE_HIT_SSDONE 0x00000008 -/* Attach to insert probes on any functions which should be ignored*/ -#define __kprobes __attribute__((__section__(".kprobes.text"))) - #else /* CONFIG_KPROBES */ typedef int kprobe_opcode_t; struct arch_specific_insn { int dummy; }; -#define __kprobes - #endif /* CONFIG_KPROBES */ struct kprobe; @@ -268,10 +264,36 @@ extern void arch_arm_kprobe(struct kprobe *p); extern void arch_disarm_kprobe(struct kprobe *p); extern int arch_init_kprobes(void); extern void show_registers(struct pt_regs *regs); -extern kprobe_opcode_t *get_insn_slot(void); -extern void free_insn_slot(kprobe_opcode_t *slot, int dirty); extern void kprobes_inc_nmissed_count(struct kprobe *p); +struct kprobe_insn_cache { + struct mutex mutex; + void *(*alloc)(void); /* allocate insn page */ + void (*free)(void *); /* free insn page */ + struct list_head pages; /* list of kprobe_insn_page */ + size_t insn_size; /* size of instruction slot */ + int nr_garbage; +}; + +extern kprobe_opcode_t *__get_insn_slot(struct kprobe_insn_cache *c); +extern void __free_insn_slot(struct kprobe_insn_cache *c, + kprobe_opcode_t *slot, int dirty); + +#define DEFINE_INSN_CACHE_OPS(__name) \ +extern struct kprobe_insn_cache kprobe_##__name##_slots; \ + \ +static inline kprobe_opcode_t *get_##__name##_slot(void) \ +{ \ + return __get_insn_slot(&kprobe_##__name##_slots); \ +} \ + \ +static inline void free_##__name##_slot(kprobe_opcode_t *slot, int dirty)\ +{ \ + __free_insn_slot(&kprobe_##__name##_slots, slot, dirty); \ +} \ + +DEFINE_INSN_CACHE_OPS(insn); + #ifdef CONFIG_OPTPROBES /* * Internal structure for direct jump optimized probe @@ -291,13 +313,13 @@ extern void arch_optimize_kprobes(struct list_head *oplist); extern void arch_unoptimize_kprobes(struct list_head *oplist, struct list_head *done_list); extern void arch_unoptimize_kprobe(struct optimized_kprobe *op); -extern kprobe_opcode_t *get_optinsn_slot(void); -extern void free_optinsn_slot(kprobe_opcode_t *slot, int dirty); extern int arch_within_optimized_kprobe(struct optimized_kprobe *op, unsigned long addr); extern void opt_pre_handler(struct kprobe *p, struct pt_regs *regs); +DEFINE_INSN_CACHE_OPS(optinsn); + #ifdef CONFIG_SYSCTL extern int sysctl_kprobes_optimization; extern int proc_kprobes_optimization_handler(struct ctl_table *table, diff --git a/include/linux/kref.h b/include/linux/kref.h index 4972e6e9ca93..484604d184be 100644 --- a/include/linux/kref.h +++ b/include/linux/kref.h @@ -19,6 +19,7 @@ #include <linux/atomic.h> #include <linux/kernel.h> #include <linux/mutex.h> +#include <linux/spinlock.h> struct kref { atomic_t refcount; @@ -39,8 +40,11 @@ static inline void kref_init(struct kref *kref) */ static inline void kref_get(struct kref *kref) { - WARN_ON(!atomic_read(&kref->refcount)); - atomic_inc(&kref->refcount); + /* If refcount was 0 before incrementing then we have a race + * condition when this kref is freeing by some other thread right now. + * In this case one should use kref_get_unless_zero() + */ + WARN_ON_ONCE(atomic_inc_return(&kref->refcount) < 2); } /** @@ -95,12 +99,44 @@ static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref) return kref_sub(kref, 1, release); } +/** + * kref_put_spinlock_irqsave - decrement refcount for object. + * @kref: object. + * @release: pointer to the function that will clean up the object when the + * last reference to the object is released. + * This pointer is required, and it is not acceptable to pass kfree + * in as this function. + * @lock: lock to take in release case + * + * Behaves identical to kref_put with one exception. If the reference count + * drops to zero, the lock will be taken atomically wrt dropping the reference + * count. The release function has to call spin_unlock() without _irqrestore. + */ +static inline int kref_put_spinlock_irqsave(struct kref *kref, + void (*release)(struct kref *kref), + spinlock_t *lock) +{ + unsigned long flags; + + WARN_ON(release == NULL); + if (atomic_add_unless(&kref->refcount, -1, 1)) + return 0; + spin_lock_irqsave(lock, flags); + if (atomic_dec_and_test(&kref->refcount)) { + release(kref); + local_irq_restore(flags); + return 1; + } + spin_unlock_irqrestore(lock, flags); + return 0; +} + static inline int kref_put_mutex(struct kref *kref, void (*release)(struct kref *kref), struct mutex *lock) { WARN_ON(release == NULL); - if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) { + if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) { mutex_lock(lock); if (unlikely(!atomic_dec_and_test(&kref->refcount))) { mutex_unlock(lock); diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 8d816646f766..7dcef3317689 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -43,6 +43,7 @@ bool kthread_should_stop(void); bool kthread_should_park(void); bool kthread_freezable_should_stop(bool *was_frozen); void *kthread_data(struct task_struct *k); +void *probe_kthread_data(struct task_struct *k); int kthread_park(struct task_struct *k); void kthread_unpark(struct task_struct *k); void kthread_parkme(void); diff --git a/include/linux/ktime.h b/include/linux/ktime.h index e83512f63df5..31c0cd1c941a 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -69,7 +69,7 @@ typedef union ktime ktime_t; /* Kill this */ * @secs: seconds to set * @nsecs: nanoseconds to set * - * Return the ktime_t representation of the value + * Return: The ktime_t representation of the value. */ static inline ktime_t ktime_set(const long secs, const unsigned long nsecs) { @@ -151,7 +151,7 @@ static inline ktime_t ktime_set(const long secs, const unsigned long nsecs) * @lhs: minuend * @rhs: subtrahend * - * Returns the remainder of the subtraction + * Return: The remainder of the subtraction. */ static inline ktime_t ktime_sub(const ktime_t lhs, const ktime_t rhs) { @@ -169,7 +169,7 @@ static inline ktime_t ktime_sub(const ktime_t lhs, const ktime_t rhs) * @add1: addend1 * @add2: addend2 * - * Returns the sum of @add1 and @add2. + * Return: The sum of @add1 and @add2. */ static inline ktime_t ktime_add(const ktime_t add1, const ktime_t add2) { @@ -195,7 +195,7 @@ static inline ktime_t ktime_add(const ktime_t add1, const ktime_t add2) * @kt: addend * @nsec: the scalar nsec value to add * - * Returns the sum of @kt and @nsec in ktime_t format + * Return: The sum of @kt and @nsec in ktime_t format. */ extern ktime_t ktime_add_ns(const ktime_t kt, u64 nsec); @@ -204,7 +204,7 @@ extern ktime_t ktime_add_ns(const ktime_t kt, u64 nsec); * @kt: minuend * @nsec: the scalar nsec value to subtract * - * Returns the subtraction of @nsec from @kt in ktime_t format + * Return: The subtraction of @nsec from @kt in ktime_t format. */ extern ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec); @@ -212,7 +212,7 @@ extern ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec); * timespec_to_ktime - convert a timespec to ktime_t format * @ts: the timespec variable to convert * - * Returns a ktime_t variable with the converted timespec value + * Return: A ktime_t variable with the converted timespec value. */ static inline ktime_t timespec_to_ktime(const struct timespec ts) { @@ -224,19 +224,20 @@ static inline ktime_t timespec_to_ktime(const struct timespec ts) * timeval_to_ktime - convert a timeval to ktime_t format * @tv: the timeval variable to convert * - * Returns a ktime_t variable with the converted timeval value + * Return: A ktime_t variable with the converted timeval value. */ static inline ktime_t timeval_to_ktime(const struct timeval tv) { return (ktime_t) { .tv = { .sec = (s32)tv.tv_sec, - .nsec = (s32)tv.tv_usec * 1000 } }; + .nsec = (s32)(tv.tv_usec * + NSEC_PER_USEC) } }; } /** * ktime_to_timespec - convert a ktime_t variable to timespec format * @kt: the ktime_t variable to convert * - * Returns the timespec representation of the ktime value + * Return: The timespec representation of the ktime value. */ static inline struct timespec ktime_to_timespec(const ktime_t kt) { @@ -248,7 +249,7 @@ static inline struct timespec ktime_to_timespec(const ktime_t kt) * ktime_to_timeval - convert a ktime_t variable to timeval format * @kt: the ktime_t variable to convert * - * Returns the timeval representation of the ktime value + * Return: The timeval representation of the ktime value. */ static inline struct timeval ktime_to_timeval(const ktime_t kt) { @@ -261,7 +262,7 @@ static inline struct timeval ktime_to_timeval(const ktime_t kt) * ktime_to_ns - convert a ktime_t variable to scalar nanoseconds * @kt: the ktime_t variable to convert * - * Returns the scalar nanoseconds representation of @kt + * Return: The scalar nanoseconds representation of @kt. */ static inline s64 ktime_to_ns(const ktime_t kt) { @@ -275,7 +276,9 @@ static inline s64 ktime_to_ns(const ktime_t kt) * @cmp1: comparable1 * @cmp2: comparable2 * - * Compare two ktime_t variables, returns 1 if equal + * Compare two ktime_t variables. + * + * Return: 1 if equal. */ static inline int ktime_equal(const ktime_t cmp1, const ktime_t cmp2) { @@ -287,7 +290,7 @@ static inline int ktime_equal(const ktime_t cmp1, const ktime_t cmp2) * @cmp1: comparable1 * @cmp2: comparable2 * - * Returns ... + * Return: ... * cmp1 < cmp2: return <0 * cmp1 == cmp2: return 0 * cmp1 > cmp2: return >0 @@ -320,16 +323,40 @@ static inline s64 ktime_us_delta(const ktime_t later, const ktime_t earlier) static inline ktime_t ktime_add_us(const ktime_t kt, const u64 usec) { - return ktime_add_ns(kt, usec * 1000); + return ktime_add_ns(kt, usec * NSEC_PER_USEC); +} + +static inline ktime_t ktime_add_ms(const ktime_t kt, const u64 msec) +{ + return ktime_add_ns(kt, msec * NSEC_PER_MSEC); } static inline ktime_t ktime_sub_us(const ktime_t kt, const u64 usec) { - return ktime_sub_ns(kt, usec * 1000); + return ktime_sub_ns(kt, usec * NSEC_PER_USEC); } extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs); +/** + * ktime_to_timespec_cond - convert a ktime_t variable to timespec + * format only if the variable contains data + * @kt: the ktime_t variable to convert + * @ts: the timespec variable to store the result in + * + * Return: %true if there was a successful conversion, %false if kt was 0. + */ +static inline __must_check bool ktime_to_timespec_cond(const ktime_t kt, + struct timespec *ts) +{ + if (kt.tv64) { + *ts = ktime_to_timespec(kt); + return true; + } else { + return false; + } +} + /* * The resolution of the clocks. The resolution value is returned in * the clock_getres() system call to give application programmers an @@ -348,7 +375,15 @@ extern void ktime_get_ts(struct timespec *ts); static inline ktime_t ns_to_ktime(u64 ns) { static const ktime_t ktime_zero = { .tv64 = 0 }; + return ktime_add_ns(ktime_zero, ns); } +static inline ktime_t ms_to_ktime(u64 ms) +{ + static const ktime_t ktime_zero = { .tv64 = 0 }; + + return ktime_add_ms(ktime_zero, ms); +} + #endif diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index cad77fe09d77..749bdb12cd15 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -23,6 +23,7 @@ #include <linux/ratelimit.h> #include <linux/err.h> #include <linux/irqflags.h> +#include <linux/context_tracking.h> #include <asm/signal.h> #include <linux/kvm.h> @@ -84,6 +85,12 @@ static inline bool is_noslot_pfn(pfn_t pfn) return pfn == KVM_PFN_NOSLOT; } +/* + * architectures with KVM_HVA_ERR_BAD other than PAGE_OFFSET (e.g. s390) + * provide own defines and kvm_is_error_hva + */ +#ifndef KVM_HVA_ERR_BAD + #define KVM_HVA_ERR_BAD (PAGE_OFFSET) #define KVM_HVA_ERR_RO_BAD (PAGE_OFFSET + PAGE_SIZE) @@ -92,6 +99,8 @@ static inline bool kvm_is_error_hva(unsigned long addr) return addr >= PAGE_OFFSET; } +#endif + #define KVM_ERR_PTR_BAD_PAGE (ERR_PTR(-ENOENT)) static inline bool is_error_page(struct page *page) @@ -117,14 +126,14 @@ static inline bool is_error_page(struct page *page) #define KVM_REQ_APF_HALT 12 #define KVM_REQ_STEAL_UPDATE 13 #define KVM_REQ_NMI 14 -#define KVM_REQ_IMMEDIATE_EXIT 15 -#define KVM_REQ_PMU 16 -#define KVM_REQ_PMI 17 -#define KVM_REQ_WATCHDOG 18 -#define KVM_REQ_MASTERCLOCK_UPDATE 19 -#define KVM_REQ_MCLOCK_INPROGRESS 20 -#define KVM_REQ_EPR_EXIT 21 -#define KVM_REQ_EOIBITMAP 22 +#define KVM_REQ_PMU 15 +#define KVM_REQ_PMI 16 +#define KVM_REQ_WATCHDOG 17 +#define KVM_REQ_MASTERCLOCK_UPDATE 18 +#define KVM_REQ_MCLOCK_INPROGRESS 19 +#define KVM_REQ_EPR_EXIT 20 +#define KVM_REQ_SCAN_IOAPIC 21 +#define KVM_REQ_GLOBAL_CLOCK_UPDATE 22 #define KVM_USERSPACE_IRQ_SOURCE_ID 0 #define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID 1 @@ -133,6 +142,9 @@ struct kvm; struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; +extern raw_spinlock_t kvm_lock; +extern struct list_head vm_list; + struct kvm_io_range { gpa_t addr; int len; @@ -142,20 +154,26 @@ struct kvm_io_range { #define NR_IOBUS_DEVS 1000 struct kvm_io_bus { - int dev_count; + int dev_count; + int ioeventfd_count; struct kvm_io_range range[]; }; enum kvm_bus { KVM_MMIO_BUS, KVM_PIO_BUS, + KVM_VIRTIO_CCW_NOTIFY_BUS, KVM_NR_BUSES }; int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, int len, const void *val); +int kvm_io_bus_write_cookie(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, + int len, const void *val, long cookie); int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, int len, void *val); +int kvm_io_bus_read_cookie(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, + int len, void *val, long cookie); int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, int len, struct kvm_io_device *dev); int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, @@ -172,7 +190,6 @@ struct kvm_async_pf { unsigned long addr; struct kvm_arch_async_pf arch; struct page *page; - bool done; }; void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu); @@ -252,6 +269,7 @@ struct kvm_vcpu { bool dy_eligible; } spin_loop; #endif + bool preempted; struct kvm_vcpu_arch arch; }; @@ -285,7 +303,8 @@ struct kvm_kernel_irq_routing_entry { u32 gsi; u32 type; int (*set)(struct kvm_kernel_irq_routing_entry *e, - struct kvm *kvm, int irq_source_id, int level); + struct kvm *kvm, int irq_source_id, int level, + bool line_status); union { struct { unsigned irqchip; @@ -296,10 +315,10 @@ struct kvm_kernel_irq_routing_entry { struct hlist_node link; }; -#ifdef __KVM_HAVE_IOAPIC +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING struct kvm_irq_routing_table { - int chip[KVM_NR_IRQCHIPS][KVM_IOAPIC_NUM_PINS]; + int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS]; struct kvm_kernel_irq_routing_entry *rt_entries; u32 nr_rt_entries; /* @@ -385,6 +404,7 @@ struct kvm { long mmu_notifier_count; #endif long tlbs_dirty; + struct list_head devices; }; #define kvm_err(fmt, ...) \ @@ -424,6 +444,19 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu); int __must_check vcpu_load(struct kvm_vcpu *vcpu); void vcpu_put(struct kvm_vcpu *vcpu); +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING +int kvm_irqfd_init(void); +void kvm_irqfd_exit(void); +#else +static inline int kvm_irqfd_init(void) +{ + return 0; +} + +static inline void kvm_irqfd_exit(void) +{ +} +#endif int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, struct module *module); void kvm_exit(void); @@ -452,24 +485,40 @@ id_to_memslot(struct kvm_memslots *slots, int id) return slot; } +/* + * KVM_SET_USER_MEMORY_REGION ioctl allows the following operations: + * - create a new memory slot + * - delete an existing memory slot + * - modify an existing memory slot + * -- move it in the guest physical memory space + * -- just change its flags + * + * Since flags can be changed by some of these operations, the following + * differentiation is the best we can do for __kvm_set_memory_region(): + */ +enum kvm_mr_change { + KVM_MR_CREATE, + KVM_MR_DELETE, + KVM_MR_MOVE, + KVM_MR_FLAGS_ONLY, +}; + int kvm_set_memory_region(struct kvm *kvm, - struct kvm_userspace_memory_region *mem, - bool user_alloc); + struct kvm_userspace_memory_region *mem); int __kvm_set_memory_region(struct kvm *kvm, - struct kvm_userspace_memory_region *mem, - bool user_alloc); + struct kvm_userspace_memory_region *mem); void kvm_arch_free_memslot(struct kvm_memory_slot *free, struct kvm_memory_slot *dont); int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages); +void kvm_arch_memslots_updated(struct kvm *kvm); int kvm_arch_prepare_memory_region(struct kvm *kvm, struct kvm_memory_slot *memslot, - struct kvm_memory_slot old, struct kvm_userspace_memory_region *mem, - bool user_alloc); + enum kvm_mr_change change); void kvm_arch_commit_memory_region(struct kvm *kvm, struct kvm_userspace_memory_region *mem, - struct kvm_memory_slot old, - bool user_alloc); + const struct kvm_memory_slot *old, + enum kvm_mr_change change); bool kvm_largepages_enabled(void); void kvm_disable_largepages(void); /* flush all memory translations */ @@ -483,6 +532,7 @@ int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages, struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn); unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn); +unsigned long gfn_to_hva_prot(struct kvm *kvm, gfn_t gfn, bool *writable); unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn); void kvm_release_page_clean(struct page *page); void kvm_release_page_dirty(struct page *page); @@ -518,7 +568,7 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data, int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, void *data, unsigned long len); int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, - gpa_t gpa); + gpa_t gpa, unsigned long len); int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len); int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len); struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); @@ -539,7 +589,7 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu); void kvm_flush_remote_tlbs(struct kvm *kvm); void kvm_reload_remote_mmus(struct kvm *kvm); void kvm_make_mclock_inprogress_request(struct kvm *kvm); -void kvm_make_update_eoibitmap_request(struct kvm *kvm); +void kvm_make_scan_ioapic_request(struct kvm *kvm); long kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg); @@ -555,10 +605,9 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log); int kvm_vm_ioctl_set_memory_region(struct kvm *kvm, - struct - kvm_userspace_memory_region *mem, - bool user_alloc); -int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level); + struct kvm_userspace_memory_region *mem); +int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level, + bool line_status); long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg); @@ -632,7 +681,6 @@ static inline wait_queue_head_t *kvm_arch_vcpu_wq(struct kvm_vcpu *vcpu) int kvm_arch_init_vm(struct kvm *kvm, unsigned long type); void kvm_arch_destroy_vm(struct kvm *kvm); -void kvm_free_all_assigned_devices(struct kvm *kvm); void kvm_arch_sync_events(struct kvm *kvm); int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu); @@ -684,15 +732,11 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq, void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, bool mask); -#ifdef __KVM_HAVE_IOAPIC -void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic, - union kvm_ioapic_redirect_entry *entry, - unsigned long *deliver_bitmask); -#endif -int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level); +int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, + bool line_status); int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level); int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm, - int irq_source_id, int level); + int irq_source_id, int level, bool line_status); bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin); void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin); void kvm_register_irq_ack_notifier(struct kvm *kvm, @@ -705,7 +749,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); /* For vcpu->arch.iommu_flags */ #define KVM_IOMMU_CACHE_COHERENCY 0x1 -#ifdef CONFIG_IOMMU_API +#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot); void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot); int kvm_iommu_map_guest(struct kvm *kvm); @@ -714,7 +758,7 @@ int kvm_assign_device(struct kvm *kvm, struct kvm_assigned_dev_kernel *assigned_dev); int kvm_deassign_device(struct kvm *kvm, struct kvm_assigned_dev_kernel *assigned_dev); -#else /* CONFIG_IOMMU_API */ +#else static inline int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) { @@ -726,64 +770,11 @@ static inline void kvm_iommu_unmap_pages(struct kvm *kvm, { } -static inline int kvm_iommu_map_guest(struct kvm *kvm) -{ - return -ENODEV; -} - static inline int kvm_iommu_unmap_guest(struct kvm *kvm) { return 0; } - -static inline int kvm_assign_device(struct kvm *kvm, - struct kvm_assigned_dev_kernel *assigned_dev) -{ - return 0; -} - -static inline int kvm_deassign_device(struct kvm *kvm, - struct kvm_assigned_dev_kernel *assigned_dev) -{ - return 0; -} -#endif /* CONFIG_IOMMU_API */ - -static inline void __guest_enter(void) -{ - /* - * This is running in ioctl context so we can avoid - * the call to vtime_account() with its unnecessary idle check. - */ - vtime_account_system(current); - current->flags |= PF_VCPU; -} - -static inline void __guest_exit(void) -{ - /* - * This is running in ioctl context so we can avoid - * the call to vtime_account() with its unnecessary idle check. - */ - vtime_account_system(current); - current->flags &= ~PF_VCPU; -} - -#ifdef CONFIG_CONTEXT_TRACKING -extern void guest_enter(void); -extern void guest_exit(void); - -#else /* !CONFIG_CONTEXT_TRACKING */ -static inline void guest_enter(void) -{ - __guest_enter(); -} - -static inline void guest_exit(void) -{ - __guest_exit(); -} -#endif /* !CONFIG_CONTEXT_TRACKING */ +#endif static inline void kvm_guest_enter(void) { @@ -921,7 +912,7 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq) } #endif -#ifdef KVM_CAP_IRQ_ROUTING +#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING #define KVM_MAX_IRQ_ROUTES 1024 @@ -930,6 +921,9 @@ int kvm_set_irq_routing(struct kvm *kvm, const struct kvm_irq_routing_entry *entries, unsigned nr, unsigned flags); +int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, + struct kvm_kernel_irq_routing_entry *e, + const struct kvm_irq_routing_entry *ue); void kvm_free_irq_routing(struct kvm *kvm); int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); @@ -998,11 +992,13 @@ static inline bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) { return true; } #endif -#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT +#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, unsigned long arg); +void kvm_free_all_assigned_devices(struct kvm *kvm); + #else static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, @@ -1011,6 +1007,8 @@ static inline long kvm_vm_ioctl_assigned_device(struct kvm *kvm, unsigned ioctl, return -ENOTTY; } +static inline void kvm_free_all_assigned_devices(struct kvm *kvm) {} + #endif static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu) @@ -1028,6 +1026,46 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu) } } +extern bool kvm_rebooting; + +struct kvm_device_ops; + +struct kvm_device { + struct kvm_device_ops *ops; + struct kvm *kvm; + void *private; + struct list_head vm_node; +}; + +/* create, destroy, and name are mandatory */ +struct kvm_device_ops { + const char *name; + int (*create)(struct kvm_device *dev, u32 type); + + /* + * Destroy is responsible for freeing dev. + * + * Destroy may be called before or after destructors are called + * on emulated I/O regions, depending on whether a reference is + * held by a vcpu or other kvm component that gets destroyed + * after the emulated I/O. + */ + void (*destroy)(struct kvm_device *dev); + + int (*set_attr)(struct kvm_device *dev, struct kvm_device_attr *attr); + int (*get_attr)(struct kvm_device *dev, struct kvm_device_attr *attr); + int (*has_attr)(struct kvm_device *dev, struct kvm_device_attr *attr); + long (*ioctl)(struct kvm_device *dev, unsigned int ioctl, + unsigned long arg); +}; + +void kvm_device_get(struct kvm_device *dev); +void kvm_device_put(struct kvm_device *dev); +struct kvm_device *kvm_device_from_filp(struct file *filp); + +extern struct kvm_device_ops kvm_mpic_ops; +extern struct kvm_device_ops kvm_xics_ops; + #ifdef CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT static inline void kvm_vcpu_set_in_spin_loop(struct kvm_vcpu *vcpu, bool val) diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h index fa7cc7244cbd..b0bcce0ddc95 100644 --- a/include/linux/kvm_types.h +++ b/include/linux/kvm_types.h @@ -71,6 +71,7 @@ struct gfn_to_hva_cache { u64 generation; gpa_t gpa; unsigned long hva; + unsigned long len; struct kvm_memory_slot *memslot; }; diff --git a/include/linux/lcd.h b/include/linux/lcd.h index e00c3b0ebc6b..504f6246f38f 100644 --- a/include/linux/lcd.h +++ b/include/linux/lcd.h @@ -112,7 +112,12 @@ static inline void lcd_set_power(struct lcd_device *ld, int power) extern struct lcd_device *lcd_device_register(const char *name, struct device *parent, void *devdata, struct lcd_ops *ops); +extern struct lcd_device *devm_lcd_device_register(struct device *dev, + const char *name, struct device *parent, + void *devdata, struct lcd_ops *ops); extern void lcd_device_unregister(struct lcd_device *ld); +extern void devm_lcd_device_unregister(struct device *dev, + struct lcd_device *ld); #define to_lcd_device(obj) container_of(obj, struct lcd_device, dev) diff --git a/include/linux/leds.h b/include/linux/leds.h index 0d9b5eed714e..0287ab296689 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -142,6 +142,10 @@ extern void led_set_brightness(struct led_classdev *led_cdev, /* * LED Triggers */ +/* Registration functions for simple triggers */ +#define DEFINE_LED_TRIGGER(x) static struct led_trigger *x; +#define DEFINE_LED_TRIGGER_GLOBAL(x) struct led_trigger *x; + #ifdef CONFIG_LEDS_TRIGGERS #define TRIG_NAME_MAX 50 @@ -164,9 +168,6 @@ struct led_trigger { extern int led_trigger_register(struct led_trigger *trigger); extern void led_trigger_unregister(struct led_trigger *trigger); -/* Registration functions for simple triggers */ -#define DEFINE_LED_TRIGGER(x) static struct led_trigger *x; -#define DEFINE_LED_TRIGGER_GLOBAL(x) struct led_trigger *x; extern void led_trigger_register_simple(const char *name, struct led_trigger **trigger); extern void led_trigger_unregister_simple(struct led_trigger *trigger); @@ -199,20 +200,30 @@ extern void led_trigger_rename_static(const char *name, #else -/* Triggers aren't active - null macros */ -#define DEFINE_LED_TRIGGER(x) -#define DEFINE_LED_TRIGGER_GLOBAL(x) -#define led_trigger_register_simple(x, y) do {} while(0) -#define led_trigger_unregister_simple(x) do {} while(0) -#define led_trigger_event(x, y) do {} while(0) +/* Trigger has no members */ +struct led_trigger {}; -#endif +/* Trigger inline empty functions */ +static inline void led_trigger_register_simple(const char *name, + struct led_trigger **trigger) {} +static inline void led_trigger_unregister_simple(struct led_trigger *trigger) {} +static inline void led_trigger_event(struct led_trigger *trigger, + enum led_brightness event) {} +#endif /* CONFIG_LEDS_TRIGGERS */ /* Trigger specific functions */ #ifdef CONFIG_LEDS_TRIGGER_IDE_DISK extern void ledtrig_ide_activity(void); #else -#define ledtrig_ide_activity() do {} while(0) +static inline void ledtrig_ide_activity(void) {} +#endif + +#if defined(CONFIG_LEDS_TRIGGER_CAMERA) || defined(CONFIG_LEDS_TRIGGER_CAMERA_MODULE) +extern void ledtrig_flash_ctrl(bool on); +extern void ledtrig_torch_ctrl(bool on); +#else +static inline void ledtrig_flash_ctrl(bool on) {} +static inline void ledtrig_torch_ctrl(bool on) {} #endif /* diff --git a/include/linux/libata.h b/include/linux/libata.h index 91c9d109e5f1..0e23c26485f4 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -138,6 +138,22 @@ enum { ATA_SHT_THIS_ID = -1, ATA_SHT_USE_CLUSTERING = 1, + /* struct ata_taskfile flags */ + ATA_TFLAG_LBA48 = (1 << 0), /* enable 48-bit LBA and "HOB" */ + ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */ + ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */ + ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */ + ATA_TFLAG_LBA = (1 << 4), /* enable LBA */ + ATA_TFLAG_FUA = (1 << 5), /* enable FUA */ + ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */ + + /* protocol flags */ + ATA_PROT_FLAG_PIO = (1 << 0), /* is PIO */ + ATA_PROT_FLAG_DMA = (1 << 1), /* is DMA */ + ATA_PROT_FLAG_DATA = ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA, + ATA_PROT_FLAG_NCQ = (1 << 2), /* is NCQ */ + ATA_PROT_FLAG_ATAPI = (1 << 3), /* is ATAPI */ + /* struct ata_device stuff */ ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */ ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */ @@ -156,6 +172,7 @@ enum { ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */ ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */ ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */ + ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */ ATA_DFLAG_INIT_MASK = (1 << 24) - 1, ATA_DFLAG_DETACH = (1 << 24), @@ -207,6 +224,7 @@ enum { ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */ ATA_FLAG_AN = (1 << 18), /* controller supports AN */ ATA_FLAG_PMP = (1 << 19), /* controller supports PMP */ + ATA_FLAG_FPDMA_AUX = (1 << 20), /* controller supports H2DFIS aux field */ ATA_FLAG_EM = (1 << 21), /* driver supports enclosure * management */ ATA_FLAG_SW_ACTIVITY = (1 << 22), /* driver supports sw activity @@ -398,6 +416,8 @@ enum { ATA_HORKAGE_NOSETXFER = (1 << 14), /* skip SETXFER, SATA only */ ATA_HORKAGE_BROKEN_FPDMA_AA = (1 << 15), /* skip AA */ ATA_HORKAGE_DUMP_ID = (1 << 16), /* dump IDENTIFY data */ + ATA_HORKAGE_MAX_SEC_LBA48 = (1 << 17), /* Set max sects to 65535 */ + ATA_HORKAGE_ATAPI_DMADIR = (1 << 18), /* device requires dmadir */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ @@ -516,6 +536,33 @@ enum sw_activity { BLINK_OFF, }; +struct ata_taskfile { + unsigned long flags; /* ATA_TFLAG_xxx */ + u8 protocol; /* ATA_PROT_xxx */ + + u8 ctl; /* control reg */ + + u8 hob_feature; /* additional data */ + u8 hob_nsect; /* to support LBA48 */ + u8 hob_lbal; + u8 hob_lbam; + u8 hob_lbah; + + u8 feature; + u8 nsect; + u8 lbal; + u8 lbam; + u8 lbah; + + u8 device; + + u8 command; /* IO operation */ + + u32 auxiliary; /* auxiliary field */ + /* from SATA 3.1 and */ + /* ATA-8 ACS-3 */ +}; + #ifdef CONFIG_ATA_SFF struct ata_ioports { void __iomem *cmd_addr; @@ -658,6 +705,9 @@ struct ata_device { /* DEVSLP Timing Variables from Identify Device Data Log */ u8 devslp_timing[ATA_LOG_DEVSLP_SIZE]; + /* NCQ send and receive log subcommand support */ + u8 ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_SIZE]; + /* error history */ int spdn_cnt; /* ering is CLEAR_END, read comment above CLEAR_END */ @@ -745,6 +795,7 @@ struct ata_port { /* Flags that change dynamically, protected by ap->lock */ unsigned int pflags; /* ATA_PFLAG_xxx */ unsigned int print_id; /* user visible unique port ID */ + unsigned int local_port_no; /* host local port num */ unsigned int port_no; /* 0 based port no. inside the host */ #ifdef CONFIG_ATA_SFF @@ -907,6 +958,9 @@ struct ata_port_operations { ssize_t (*sw_activity_show)(struct ata_device *dev, char *buf); ssize_t (*sw_activity_store)(struct ata_device *dev, enum sw_activity val); + ssize_t (*transmit_led_message)(struct ata_port *ap, u32 state, + ssize_t size); + /* * Obsolete */ @@ -953,6 +1007,69 @@ extern const unsigned long sata_deb_timing_long[]; extern struct ata_port_operations ata_dummy_port_ops; extern const struct ata_port_info ata_dummy_port_info; +/* + * protocol tests + */ +static inline unsigned int ata_prot_flags(u8 prot) +{ + switch (prot) { + case ATA_PROT_NODATA: + return 0; + case ATA_PROT_PIO: + return ATA_PROT_FLAG_PIO; + case ATA_PROT_DMA: + return ATA_PROT_FLAG_DMA; + case ATA_PROT_NCQ: + return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ; + case ATAPI_PROT_NODATA: + return ATA_PROT_FLAG_ATAPI; + case ATAPI_PROT_PIO: + return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO; + case ATAPI_PROT_DMA: + return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA; + } + return 0; +} + +static inline int ata_is_atapi(u8 prot) +{ + return ata_prot_flags(prot) & ATA_PROT_FLAG_ATAPI; +} + +static inline int ata_is_nodata(u8 prot) +{ + return !(ata_prot_flags(prot) & ATA_PROT_FLAG_DATA); +} + +static inline int ata_is_pio(u8 prot) +{ + return ata_prot_flags(prot) & ATA_PROT_FLAG_PIO; +} + +static inline int ata_is_dma(u8 prot) +{ + return ata_prot_flags(prot) & ATA_PROT_FLAG_DMA; +} + +static inline int ata_is_ncq(u8 prot) +{ + return ata_prot_flags(prot) & ATA_PROT_FLAG_NCQ; +} + +static inline int ata_is_data(u8 prot) +{ + return ata_prot_flags(prot) & ATA_PROT_FLAG_DATA; +} + +static inline int is_multi_taskfile(struct ata_taskfile *tf) +{ + return (tf->command == ATA_CMD_READ_MULTI) || + (tf->command == ATA_CMD_WRITE_MULTI) || + (tf->command == ATA_CMD_READ_MULTI_EXT) || + (tf->command == ATA_CMD_WRITE_MULTI_EXT) || + (tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT); +} + static inline const unsigned long * sata_ehc_deb_timing(struct ata_eh_context *ehc) { @@ -1136,8 +1253,6 @@ int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm); int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *stm); unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev, const struct ata_acpi_gtm *gtm); -acpi_handle ata_ap_acpi_handle(struct ata_port *ap); -acpi_handle ata_dev_acpi_handle(struct ata_device *dev); int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm); #else static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) @@ -1491,6 +1606,13 @@ static inline int ata_ncq_enabled(struct ata_device *dev) ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ; } +static inline bool ata_fpdma_dsm_supported(struct ata_device *dev) +{ + return (dev->flags & ATA_DFLAG_NCQ_SEND_RECV) && + (dev->ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_DSM_OFFSET] & + ATA_LOG_NCQ_SEND_RECV_DSM_TRIM); +} + static inline void ata_qc_set_polling(struct ata_queued_cmd *qc) { qc->tf.ctl |= ATA_NIEN; diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 807f1e533226..d3e8ad23a8e0 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -2,6 +2,8 @@ #define _LINUX_LINKAGE_H #include <linux/compiler.h> +#include <linux/stringify.h> +#include <linux/export.h> #include <asm/linkage.h> #ifdef __cplusplus @@ -14,6 +16,20 @@ #define asmlinkage CPP_ASMLINKAGE #endif +#ifndef cond_syscall +#define cond_syscall(x) asm( \ + ".weak " VMLINUX_SYMBOL_STR(x) "\n\t" \ + ".set " VMLINUX_SYMBOL_STR(x) "," \ + VMLINUX_SYMBOL_STR(sys_ni_syscall)) +#endif + +#ifndef SYSCALL_ALIAS +#define SYSCALL_ALIAS(alias, name) asm( \ + ".globl " VMLINUX_SYMBOL_STR(alias) "\n\t" \ + ".set " VMLINUX_SYMBOL_STR(alias) "," \ + VMLINUX_SYMBOL_STR(name)) +#endif + #define __page_aligned_data __section(.data..page_aligned) __aligned(PAGE_SIZE) #define __page_aligned_bss __section(.bss..page_aligned) __aligned(PAGE_SIZE) diff --git a/include/linux/list.h b/include/linux/list.h index d991cc147c98..f4d8a2f12a33 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -362,22 +362,22 @@ static inline void list_splice_tail_init(struct list_head *list, list_entry((ptr)->next, type, member) /** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. + * list_first_entry_or_null - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note that if the list is empty, it returns NULL. */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) +#define list_first_entry_or_null(ptr, type, member) \ + (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL) /** - * __list_for_each - iterate over a list + * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. - * - * This variant doesn't differ from list_for_each() any more. - * We don't do prefetching in either case. */ -#define __list_for_each(pos, head) \ +#define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) /** @@ -667,7 +667,9 @@ static inline void hlist_move_list(struct hlist_head *old, pos = n) #define hlist_entry_safe(ptr, type, member) \ - (ptr) ? hlist_entry(ptr, type, member) : NULL + ({ typeof(ptr) ____ptr = (ptr); \ + ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ + }) /** * hlist_for_each_entry - iterate over list of given type diff --git a/include/linux/list_bl.h b/include/linux/list_bl.h index 31f9d75adc5b..2eb88556c5c5 100644 --- a/include/linux/list_bl.h +++ b/include/linux/list_bl.h @@ -125,6 +125,11 @@ static inline void hlist_bl_unlock(struct hlist_bl_head *b) __bit_spin_unlock(0, (unsigned long *)b); } +static inline bool hlist_bl_is_locked(struct hlist_bl_head *b) +{ + return bit_spin_is_locked(0, (unsigned long *)b); +} + /** * hlist_bl_for_each_entry - iterate over list of given type * @tpos: the type * to use as a loop cursor. diff --git a/include/linux/list_lru.h b/include/linux/list_lru.h new file mode 100644 index 000000000000..3ce541753c88 --- /dev/null +++ b/include/linux/list_lru.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013 Red Hat, Inc. and Parallels Inc. All rights reserved. + * Authors: David Chinner and Glauber Costa + * + * Generic LRU infrastructure + */ +#ifndef _LRU_LIST_H +#define _LRU_LIST_H + +#include <linux/list.h> +#include <linux/nodemask.h> + +/* list_lru_walk_cb has to always return one of those */ +enum lru_status { + LRU_REMOVED, /* item removed from list */ + LRU_ROTATE, /* item referenced, give another pass */ + LRU_SKIP, /* item cannot be locked, skip */ + LRU_RETRY, /* item not freeable. May drop the lock + internally, but has to return locked. */ +}; + +struct list_lru_node { + spinlock_t lock; + struct list_head list; + /* kept as signed so we can catch imbalance bugs */ + long nr_items; +} ____cacheline_aligned_in_smp; + +struct list_lru { + struct list_lru_node *node; + nodemask_t active_nodes; +}; + +void list_lru_destroy(struct list_lru *lru); +int list_lru_init(struct list_lru *lru); + +/** + * list_lru_add: add an element to the lru list's tail + * @list_lru: the lru pointer + * @item: the item to be added. + * + * If the element is already part of a list, this function returns doing + * nothing. Therefore the caller does not need to keep state about whether or + * not the element already belongs in the list and is allowed to lazy update + * it. Note however that this is valid for *a* list, not *this* list. If + * the caller organize itself in a way that elements can be in more than + * one type of list, it is up to the caller to fully remove the item from + * the previous list (with list_lru_del() for instance) before moving it + * to @list_lru + * + * Return value: true if the list was updated, false otherwise + */ +bool list_lru_add(struct list_lru *lru, struct list_head *item); + +/** + * list_lru_del: delete an element to the lru list + * @list_lru: the lru pointer + * @item: the item to be deleted. + * + * This function works analogously as list_lru_add in terms of list + * manipulation. The comments about an element already pertaining to + * a list are also valid for list_lru_del. + * + * Return value: true if the list was updated, false otherwise + */ +bool list_lru_del(struct list_lru *lru, struct list_head *item); + +/** + * list_lru_count_node: return the number of objects currently held by @lru + * @lru: the lru pointer. + * @nid: the node id to count from. + * + * Always return a non-negative number, 0 for empty lists. There is no + * guarantee that the list is not updated while the count is being computed. + * Callers that want such a guarantee need to provide an outer lock. + */ +unsigned long list_lru_count_node(struct list_lru *lru, int nid); +static inline unsigned long list_lru_count(struct list_lru *lru) +{ + long count = 0; + int nid; + + for_each_node_mask(nid, lru->active_nodes) + count += list_lru_count_node(lru, nid); + + return count; +} + +typedef enum lru_status +(*list_lru_walk_cb)(struct list_head *item, spinlock_t *lock, void *cb_arg); +/** + * list_lru_walk_node: walk a list_lru, isolating and disposing freeable items. + * @lru: the lru pointer. + * @nid: the node id to scan from. + * @isolate: callback function that is resposible for deciding what to do with + * the item currently being scanned + * @cb_arg: opaque type that will be passed to @isolate + * @nr_to_walk: how many items to scan. + * + * This function will scan all elements in a particular list_lru, calling the + * @isolate callback for each of those items, along with the current list + * spinlock and a caller-provided opaque. The @isolate callback can choose to + * drop the lock internally, but *must* return with the lock held. The callback + * will return an enum lru_status telling the list_lru infrastructure what to + * do with the object being scanned. + * + * Please note that nr_to_walk does not mean how many objects will be freed, + * just how many objects will be scanned. + * + * Return value: the number of objects effectively removed from the LRU. + */ +unsigned long list_lru_walk_node(struct list_lru *lru, int nid, + list_lru_walk_cb isolate, void *cb_arg, + unsigned long *nr_to_walk); + +static inline unsigned long +list_lru_walk(struct list_lru *lru, list_lru_walk_cb isolate, + void *cb_arg, unsigned long nr_to_walk) +{ + long isolated = 0; + int nid; + + for_each_node_mask(nid, lru->active_nodes) { + isolated += list_lru_walk_node(lru, nid, isolate, + cb_arg, &nr_to_walk); + if (nr_to_walk <= 0) + break; + } + return isolated; +} +#endif /* _LRU_LIST_H */ diff --git a/include/linux/llist.h b/include/linux/llist.h index a5199f6d0e82..8828a78dec9a 100644 --- a/include/linux/llist.h +++ b/include/linux/llist.h @@ -125,6 +125,29 @@ static inline void init_llist_head(struct llist_head *list) (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member)) /** + * llist_for_each_entry_safe - iterate over some deleted entries of lock-less list of given type + * safe against removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @node: the first entry of deleted list entries. + * @member: the name of the llist_node with the struct. + * + * In general, some entries of the lock-less list can be traversed + * safely only after being removed from list, so start with an entry + * instead of list head. + * + * If being used on entries deleted from lock-less list directly, the + * traverse order is from the newest to the oldest added entry. If + * you want to traverse from the oldest to the newest, you must + * reverse the order by yourself before traversing. + */ +#define llist_for_each_entry_safe(pos, n, node, member) \ + for (pos = llist_entry((node), typeof(*pos), member); \ + &pos->member != NULL && \ + (n = llist_entry(pos->member.next, typeof(*n), member), true); \ + pos = n) + +/** * llist_empty - tests whether a lock-less list is empty * @head: the list to test * @@ -142,6 +165,9 @@ static inline struct llist_node *llist_next(struct llist_node *node) return node->next; } +extern bool llist_add_batch(struct llist_node *new_first, + struct llist_node *new_last, + struct llist_head *head); /** * llist_add - add a new entry * @new: new entry to be added @@ -151,18 +177,7 @@ static inline struct llist_node *llist_next(struct llist_node *node) */ static inline bool llist_add(struct llist_node *new, struct llist_head *head) { - struct llist_node *entry, *old_entry; - - entry = head->first; - for (;;) { - old_entry = entry; - new->next = entry; - entry = cmpxchg(&head->first, old_entry, new); - if (entry == old_entry) - break; - } - - return old_entry == NULL; + return llist_add_batch(new, new, head); } /** @@ -178,9 +193,6 @@ static inline struct llist_node *llist_del_all(struct llist_head *head) return xchg(&head->first, NULL); } -extern bool llist_add_batch(struct llist_node *new_first, - struct llist_node *new_last, - struct llist_head *head); extern struct llist_node *llist_del_first(struct llist_head *head); #endif /* LLIST_H */ diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index f1e877b79ed8..cfc2f119779a 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -365,7 +365,7 @@ extern void lockdep_trace_alloc(gfp_t mask); #define lockdep_recursing(tsk) ((tsk)->lockdep_recursion) -#else /* !LOCKDEP */ +#else /* !CONFIG_LOCKDEP */ static inline void lockdep_off(void) { @@ -479,82 +479,36 @@ static inline void print_irqtrace_events(struct task_struct *curr) * on the per lock-class debug mode: */ -#ifdef CONFIG_DEBUG_LOCK_ALLOC -# ifdef CONFIG_PROVE_LOCKING -# define spin_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i) -# define spin_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i) -# else -# define spin_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i) -# define spin_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, NULL, i) -# endif -# define spin_release(l, n, i) lock_release(l, n, i) +#ifdef CONFIG_PROVE_LOCKING + #define lock_acquire_exclusive(l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i) + #define lock_acquire_shared(l, s, t, n, i) lock_acquire(l, s, t, 1, 2, n, i) + #define lock_acquire_shared_recursive(l, s, t, n, i) lock_acquire(l, s, t, 2, 2, n, i) #else -# define spin_acquire(l, s, t, i) do { } while (0) -# define spin_release(l, n, i) do { } while (0) + #define lock_acquire_exclusive(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, n, i) + #define lock_acquire_shared(l, s, t, n, i) lock_acquire(l, s, t, 1, 1, n, i) + #define lock_acquire_shared_recursive(l, s, t, n, i) lock_acquire(l, s, t, 2, 1, n, i) #endif -#ifdef CONFIG_DEBUG_LOCK_ALLOC -# ifdef CONFIG_PROVE_LOCKING -# define rwlock_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i) -# define rwlock_acquire_read(l, s, t, i) lock_acquire(l, s, t, 2, 2, NULL, i) -# else -# define rwlock_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i) -# define rwlock_acquire_read(l, s, t, i) lock_acquire(l, s, t, 2, 1, NULL, i) -# endif -# define rwlock_release(l, n, i) lock_release(l, n, i) -#else -# define rwlock_acquire(l, s, t, i) do { } while (0) -# define rwlock_acquire_read(l, s, t, i) do { } while (0) -# define rwlock_release(l, n, i) do { } while (0) -#endif +#define spin_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i) +#define spin_acquire_nest(l, s, t, n, i) lock_acquire_exclusive(l, s, t, n, i) +#define spin_release(l, n, i) lock_release(l, n, i) -#ifdef CONFIG_DEBUG_LOCK_ALLOC -# ifdef CONFIG_PROVE_LOCKING -# define mutex_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i) -# define mutex_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i) -# else -# define mutex_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i) -# define mutex_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, n, i) -# endif -# define mutex_release(l, n, i) lock_release(l, n, i) -#else -# define mutex_acquire(l, s, t, i) do { } while (0) -# define mutex_acquire_nest(l, s, t, n, i) do { } while (0) -# define mutex_release(l, n, i) do { } while (0) -#endif +#define rwlock_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i) +#define rwlock_acquire_read(l, s, t, i) lock_acquire_shared_recursive(l, s, t, NULL, i) +#define rwlock_release(l, n, i) lock_release(l, n, i) -#ifdef CONFIG_DEBUG_LOCK_ALLOC -# ifdef CONFIG_PROVE_LOCKING -# define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 2, NULL, i) -# define rwsem_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 2, n, i) -# define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 2, NULL, i) -# else -# define rwsem_acquire(l, s, t, i) lock_acquire(l, s, t, 0, 1, NULL, i) -# define rwsem_acquire_nest(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, n, i) -# define rwsem_acquire_read(l, s, t, i) lock_acquire(l, s, t, 1, 1, NULL, i) -# endif +#define mutex_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i) +#define mutex_acquire_nest(l, s, t, n, i) lock_acquire_exclusive(l, s, t, n, i) +#define mutex_release(l, n, i) lock_release(l, n, i) + +#define rwsem_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i) +#define rwsem_acquire_nest(l, s, t, n, i) lock_acquire_exclusive(l, s, t, n, i) +#define rwsem_acquire_read(l, s, t, i) lock_acquire_shared(l, s, t, NULL, i) # define rwsem_release(l, n, i) lock_release(l, n, i) -#else -# define rwsem_acquire(l, s, t, i) do { } while (0) -# define rwsem_acquire_nest(l, s, t, n, i) do { } while (0) -# define rwsem_acquire_read(l, s, t, i) do { } while (0) -# define rwsem_release(l, n, i) do { } while (0) -#endif -#ifdef CONFIG_DEBUG_LOCK_ALLOC -# ifdef CONFIG_PROVE_LOCKING -# define lock_map_acquire(l) lock_acquire(l, 0, 0, 0, 2, NULL, _THIS_IP_) -# define lock_map_acquire_read(l) lock_acquire(l, 0, 0, 2, 2, NULL, _THIS_IP_) -# else -# define lock_map_acquire(l) lock_acquire(l, 0, 0, 0, 1, NULL, _THIS_IP_) -# define lock_map_acquire_read(l) lock_acquire(l, 0, 0, 2, 1, NULL, _THIS_IP_) -# endif +#define lock_map_acquire(l) lock_acquire_exclusive(l, 0, 0, NULL, _THIS_IP_) +#define lock_map_acquire_read(l) lock_acquire_shared_recursive(l, 0, 0, NULL, _THIS_IP_) # define lock_map_release(l) lock_release(l, 1, _THIS_IP_) -#else -# define lock_map_acquire(l) do { } while (0) -# define lock_map_acquire_read(l) do { } while (0) -# define lock_map_release(l) do { } while (0) -#endif #ifdef CONFIG_PROVE_LOCKING # define might_lock(lock) \ diff --git a/include/linux/lockref.h b/include/linux/lockref.h new file mode 100644 index 000000000000..f279ed9a9163 --- /dev/null +++ b/include/linux/lockref.h @@ -0,0 +1,39 @@ +#ifndef __LINUX_LOCKREF_H +#define __LINUX_LOCKREF_H + +/* + * Locked reference counts. + * + * These are different from just plain atomic refcounts in that they + * are atomic with respect to the spinlock that goes with them. In + * particular, there can be implementations that don't actually get + * the spinlock for the common decrement/increment operations, but they + * still have to check that the operation is done semantically as if + * the spinlock had been taken (using a cmpxchg operation that covers + * both the lock and the count word, or using memory transactions, for + * example). + */ + +#include <linux/spinlock.h> + +struct lockref { + union { +#ifdef CONFIG_CMPXCHG_LOCKREF + aligned_u64 lock_count; +#endif + struct { + spinlock_t lock; + unsigned int count; + }; + }; +}; + +extern void lockref_get(struct lockref *); +extern int lockref_get_not_zero(struct lockref *); +extern int lockref_get_or_lock(struct lockref *); +extern int lockref_put_or_lock(struct lockref *); + +extern void lockref_mark_dead(struct lockref *); +extern int lockref_get_not_dead(struct lockref *); + +#endif /* __LINUX_LOCKREF_H */ diff --git a/include/linux/loop.h b/include/linux/loop.h deleted file mode 100644 index 460b60fa7adf..000000000000 --- a/include/linux/loop.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * include/linux/loop.h - * - * Written by Theodore Ts'o, 3/29/93. - * - * Copyright 1993 by Theodore Ts'o. Redistribution of this file is - * permitted under the GNU General Public License. - */ -#ifndef _LINUX_LOOP_H -#define _LINUX_LOOP_H - -#include <linux/bio.h> -#include <linux/blkdev.h> -#include <linux/spinlock.h> -#include <linux/mutex.h> -#include <uapi/linux/loop.h> - -/* Possible states of device */ -enum { - Lo_unbound, - Lo_bound, - Lo_rundown, -}; - -struct loop_func_table; - -struct loop_device { - int lo_number; - int lo_refcnt; - loff_t lo_offset; - loff_t lo_sizelimit; - int lo_flags; - int (*transfer)(struct loop_device *, int cmd, - struct page *raw_page, unsigned raw_off, - struct page *loop_page, unsigned loop_off, - int size, sector_t real_block); - char lo_file_name[LO_NAME_SIZE]; - char lo_crypt_name[LO_NAME_SIZE]; - char lo_encrypt_key[LO_KEY_SIZE]; - int lo_encrypt_key_size; - struct loop_func_table *lo_encryption; - __u32 lo_init[2]; - kuid_t lo_key_owner; /* Who set the key */ - int (*ioctl)(struct loop_device *, int cmd, - unsigned long arg); - - struct file * lo_backing_file; - struct block_device *lo_device; - unsigned lo_blocksize; - void *key_data; - - gfp_t old_gfp_mask; - - spinlock_t lo_lock; - struct bio_list lo_bio_list; - unsigned int lo_bio_count; - int lo_state; - struct mutex lo_ctl_mutex; - struct task_struct *lo_thread; - wait_queue_head_t lo_event; - /* wait queue for incoming requests */ - wait_queue_head_t lo_req_wait; - - struct request_queue *lo_queue; - struct gendisk *lo_disk; -}; - -/* Support for loadable transfer modules */ -struct loop_func_table { - int number; /* filter type */ - int (*transfer)(struct loop_device *lo, int cmd, - struct page *raw_page, unsigned raw_off, - struct page *loop_page, unsigned loop_off, - int size, sector_t real_block); - int (*init)(struct loop_device *, const struct loop_info64 *); - /* release is called from loop_unregister_transfer or clr_fd */ - int (*release)(struct loop_device *); - int (*ioctl)(struct loop_device *, int cmd, unsigned long arg); - struct module *owner; -}; - -int loop_register_transfer(struct loop_func_table *funcs); -int loop_unregister_transfer(int number); - -#endif diff --git a/include/linux/lru_cache.h b/include/linux/lru_cache.h index 4019013c6593..46262284de47 100644 --- a/include/linux/lru_cache.h +++ b/include/linux/lru_cache.h @@ -256,6 +256,7 @@ extern void lc_destroy(struct lru_cache *lc); extern void lc_set(struct lru_cache *lc, unsigned int enr, int index); extern void lc_del(struct lru_cache *lc, struct lc_element *element); +extern struct lc_element *lc_get_cumulative(struct lru_cache *lc, unsigned int enr); extern struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr); extern struct lc_element *lc_find(struct lru_cache *lc, unsigned int enr); extern struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr); diff --git a/include/linux/lz4.h b/include/linux/lz4.h new file mode 100644 index 000000000000..4356686b0a39 --- /dev/null +++ b/include/linux/lz4.h @@ -0,0 +1,87 @@ +#ifndef __LZ4_H__ +#define __LZ4_H__ +/* + * LZ4 Kernel Interface + * + * Copyright (C) 2013, LG Electronics, Kyungsik Lee <kyungsik.lee@lge.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. + */ +#define LZ4_MEM_COMPRESS (4096 * sizeof(unsigned char *)) +#define LZ4HC_MEM_COMPRESS (65538 * sizeof(unsigned char *)) + +/* + * lz4_compressbound() + * Provides the maximum size that LZ4 may output in a "worst case" scenario + * (input data not compressible) + */ +static inline size_t lz4_compressbound(size_t isize) +{ + return isize + (isize / 255) + 16; +} + +/* + * lz4_compress() + * src : source address of the original data + * src_len : size of the original data + * dst : output buffer address of the compressed data + * This requires 'dst' of size LZ4_COMPRESSBOUND. + * dst_len : is the output size, which is returned after compress done + * workmem : address of the working memory. + * This requires 'workmem' of size LZ4_MEM_COMPRESS. + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer and workmem must be already allocated with + * the defined size. + */ +int lz4_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem); + + /* + * lz4hc_compress() + * src : source address of the original data + * src_len : size of the original data + * dst : output buffer address of the compressed data + * This requires 'dst' of size LZ4_COMPRESSBOUND. + * dst_len : is the output size, which is returned after compress done + * workmem : address of the working memory. + * This requires 'workmem' of size LZ4HC_MEM_COMPRESS. + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer and workmem must be already allocated with + * the defined size. + */ +int lz4hc_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem); + +/* + * lz4_decompress() + * src : source address of the compressed data + * src_len : is the input size, whcih is returned after decompress done + * dest : output buffer address of the decompressed data + * actual_dest_len: is the size of uncompressed data, supposing it's known + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer must be already allocated. + * slightly faster than lz4_decompress_unknownoutputsize() + */ +int lz4_decompress(const unsigned char *src, size_t *src_len, + unsigned char *dest, size_t actual_dest_len); + +/* + * lz4_decompress_unknownoutputsize() + * src : source address of the compressed data + * src_len : is the input size, therefore the compressed size + * dest : output buffer address of the decompressed data + * dest_len: is the max size of the destination buffer, which is + * returned with actual size of decompressed data after + * decompress done + * return : Success if return 0 + * Error if return (< 0) + * note : Destination buffer must be already allocated. + */ +int lz4_decompress_unknownoutputsize(const unsigned char *src, size_t src_len, + unsigned char *dest, size_t *dest_len); +#endif diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h index dd3c34ebca9a..8e9a029e093d 100644 --- a/include/linux/marvell_phy.h +++ b/include/linux/marvell_phy.h @@ -14,6 +14,8 @@ #define MARVELL_PHY_ID_88E1149R 0x01410e50 #define MARVELL_PHY_ID_88E1240 0x01410e30 #define MARVELL_PHY_ID_88E1318S 0x01410e90 +#define MARVELL_PHY_ID_88E1116R 0x01410e40 +#define MARVELL_PHY_ID_88E1510 0x01410dd0 /* struct phy_device dev_flags definitions */ #define MARVELL_PHY_M1145_FLAGS_RESISTANCE 0x00000001 diff --git a/include/linux/math64.h b/include/linux/math64.h index b8ba85544721..69ed5f5e9f6e 100644 --- a/include/linux/math64.h +++ b/include/linux/math64.h @@ -6,7 +6,8 @@ #if BITS_PER_LONG == 64 -#define div64_long(x,y) div64_s64((x),(y)) +#define div64_long(x, y) div64_s64((x), (y)) +#define div64_ul(x, y) div64_u64((x), (y)) /** * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder @@ -30,6 +31,15 @@ static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) } /** + * div64_u64_rem - unsigned 64bit divide with 64bit divisor and remainder + */ +static inline u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder) +{ + *remainder = dividend % divisor; + return dividend / divisor; +} + +/** * div64_u64 - unsigned 64bit divide with 64bit divisor */ static inline u64 div64_u64(u64 dividend, u64 divisor) @@ -47,7 +57,8 @@ static inline s64 div64_s64(s64 dividend, s64 divisor) #elif BITS_PER_LONG == 32 -#define div64_long(x,y) div_s64((x),(y)) +#define div64_long(x, y) div_s64((x), (y)) +#define div64_ul(x, y) div_u64((x), (y)) #ifndef div_u64_rem static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) @@ -61,6 +72,10 @@ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder); #endif +#ifndef div64_u64_rem +extern u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder); +#endif + #ifndef div64_u64 extern u64 div64_u64(u64 dividend, u64 divisor); #endif diff --git a/include/linux/mbus.h b/include/linux/mbus.h index efa1a6d7aca8..345b8c53b897 100644 --- a/include/linux/mbus.h +++ b/include/linux/mbus.h @@ -11,6 +11,8 @@ #ifndef __LINUX_MBUS_H #define __LINUX_MBUS_H +struct resource; + struct mbus_dram_target_info { /* @@ -32,6 +34,20 @@ struct mbus_dram_target_info } cs[4]; }; +/* Flags for PCI/PCIe address decoding regions */ +#define MVEBU_MBUS_PCI_IO 0x1 +#define MVEBU_MBUS_PCI_MEM 0x2 +#define MVEBU_MBUS_PCI_WA 0x3 + +/* + * Magic value that explicits that we don't need a remapping-capable + * address decoding window. + */ +#define MVEBU_MBUS_NO_REMAP (0xffffffff) + +/* Maximum size of a mbus window name */ +#define MVEBU_MBUS_MAX_WINNAME_SZ 32 + /* * The Marvell mbus is to be found only on SOCs from the Orion family * at the moment. Provide a dummy stub for other architectures. @@ -44,4 +60,19 @@ static inline const struct mbus_dram_target_info *mv_mbus_dram_info(void) return NULL; } #endif -#endif + +void mvebu_mbus_get_pcie_mem_aperture(struct resource *res); +void mvebu_mbus_get_pcie_io_aperture(struct resource *res); +int mvebu_mbus_add_window_remap_by_id(unsigned int target, + unsigned int attribute, + phys_addr_t base, size_t size, + phys_addr_t remap); +int mvebu_mbus_add_window_by_id(unsigned int target, unsigned int attribute, + phys_addr_t base, size_t size); +int mvebu_mbus_del_window(phys_addr_t base, size_t size); +int mvebu_mbus_init(const char *soc, phys_addr_t mbus_phys_base, + size_t mbus_size, phys_addr_t sdram_phys_base, + size_t sdram_size); +int mvebu_mbus_dt_init(void); + +#endif /* __LINUX_MBUS_H */ diff --git a/include/linux/mei_cl_bus.h b/include/linux/mei_cl_bus.h new file mode 100644 index 000000000000..d14af7b722ef --- /dev/null +++ b/include/linux/mei_cl_bus.h @@ -0,0 +1,44 @@ +#ifndef _LINUX_MEI_CL_BUS_H +#define _LINUX_MEI_CL_BUS_H + +#include <linux/device.h> +#include <linux/uuid.h> + +struct mei_cl_device; + +struct mei_cl_driver { + struct device_driver driver; + const char *name; + + const struct mei_cl_device_id *id_table; + + int (*probe)(struct mei_cl_device *dev, + const struct mei_cl_device_id *id); + int (*remove)(struct mei_cl_device *dev); +}; + +int __mei_cl_driver_register(struct mei_cl_driver *driver, + struct module *owner); +#define mei_cl_driver_register(driver) \ + __mei_cl_driver_register(driver, THIS_MODULE) + +void mei_cl_driver_unregister(struct mei_cl_driver *driver); + +int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length); +int mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length); + +typedef void (*mei_cl_event_cb_t)(struct mei_cl_device *device, + u32 events, void *context); +int mei_cl_register_event_cb(struct mei_cl_device *device, + mei_cl_event_cb_t read_cb, void *context); + +#define MEI_CL_EVENT_RX 0 +#define MEI_CL_EVENT_TX 1 + +void *mei_cl_get_drvdata(const struct mei_cl_device *device); +void mei_cl_set_drvdata(struct mei_cl_device *device, void *data); + +int mei_cl_enable_device(struct mei_cl_device *device); +int mei_cl_disable_device(struct mei_cl_device *device); + +#endif /* _LINUX_MEI_CL_BUS_H */ diff --git a/include/linux/memblock.h b/include/linux/memblock.h index f388203db7e8..31e95acddb4d 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -60,6 +60,8 @@ int memblock_reserve(phys_addr_t base, phys_addr_t size); void memblock_trim_memory(phys_addr_t align); #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP +int memblock_search_pfn_nid(unsigned long pfn, unsigned long *start_pfn, + unsigned long *end_pfn); void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, unsigned long *out_end_pfn, int *out_nid); diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index d6183f06d8c1..ecc82b37c4cc 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -30,9 +30,21 @@ struct page; struct mm_struct; struct kmem_cache; -/* Stats that can be updated by kernel. */ -enum mem_cgroup_page_stat_item { - MEMCG_NR_FILE_MAPPED, /* # of pages charged as file rss */ +/* + * The corresponding mem_cgroup_stat_names is defined in mm/memcontrol.c, + * These two lists should keep in accord with each other. + */ +enum mem_cgroup_stat_index { + /* + * For MEM_CONTAINER_TYPE_ALL, usage = pagecache + rss. + */ + MEM_CGROUP_STAT_CACHE, /* # of pages charged as cache */ + MEM_CGROUP_STAT_RSS, /* # of pages charged as anon rss */ + MEM_CGROUP_STAT_RSS_HUGE, /* # of pages charged as anon huge */ + MEM_CGROUP_STAT_FILE_MAPPED, /* # of pages charged as file rss */ + MEM_CGROUP_STAT_WRITEBACK, /* # of pages under writeback */ + MEM_CGROUP_STAT_SWAP, /* # of pages, swapped out */ + MEM_CGROUP_STAT_NSTATS, }; struct mem_cgroup_reclaim_cookie { @@ -77,14 +89,15 @@ extern void mem_cgroup_uncharge_cache_page(struct page *page); bool __mem_cgroup_same_or_subtree(const struct mem_cgroup *root_memcg, struct mem_cgroup *memcg); -int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *memcg); +bool task_in_mem_cgroup(struct task_struct *task, + const struct mem_cgroup *memcg); extern struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page); extern struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p); extern struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm); extern struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg); -extern struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont); +extern struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *css); static inline bool mm_match_cgroup(const struct mm_struct *mm, const struct mem_cgroup *memcg) @@ -124,6 +137,48 @@ extern void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, extern void mem_cgroup_replace_page_cache(struct page *oldpage, struct page *newpage); +/** + * mem_cgroup_toggle_oom - toggle the memcg OOM killer for the current task + * @new: true to enable, false to disable + * + * Toggle whether a failed memcg charge should invoke the OOM killer + * or just return -ENOMEM. Returns the previous toggle state. + * + * NOTE: Any path that enables the OOM killer before charging must + * call mem_cgroup_oom_synchronize() afterward to finalize the + * OOM handling and clean up. + */ +static inline bool mem_cgroup_toggle_oom(bool new) +{ + bool old; + + old = current->memcg_oom.may_oom; + current->memcg_oom.may_oom = new; + + return old; +} + +static inline void mem_cgroup_enable_oom(void) +{ + bool old = mem_cgroup_toggle_oom(true); + + WARN_ON(old == true); +} + +static inline void mem_cgroup_disable_oom(void) +{ + bool old = mem_cgroup_toggle_oom(false); + + WARN_ON(old == false); +} + +static inline bool task_in_memcg_oom(struct task_struct *p) +{ + return p->memcg_oom.in_memcg_oom; +} + +bool mem_cgroup_oom_synchronize(void); + #ifdef CONFIG_MEMCG_SWAP extern int do_swap_account; #endif @@ -164,17 +219,17 @@ static inline void mem_cgroup_end_update_page_stat(struct page *page, } void mem_cgroup_update_page_stat(struct page *page, - enum mem_cgroup_page_stat_item idx, + enum mem_cgroup_stat_index idx, int val); static inline void mem_cgroup_inc_page_stat(struct page *page, - enum mem_cgroup_page_stat_item idx) + enum mem_cgroup_stat_index idx) { mem_cgroup_update_page_stat(page, idx, 1); } static inline void mem_cgroup_dec_page_stat(struct page *page, - enum mem_cgroup_page_stat_item idx) + enum mem_cgroup_stat_index idx) { mem_cgroup_update_page_stat(page, idx, -1); } @@ -273,10 +328,10 @@ static inline bool mm_match_cgroup(struct mm_struct *mm, return true; } -static inline int task_in_mem_cgroup(struct task_struct *task, - const struct mem_cgroup *memcg) +static inline bool task_in_mem_cgroup(struct task_struct *task, + const struct mem_cgroup *memcg) { - return 1; + return true; } static inline struct cgroup_subsys_state @@ -347,13 +402,36 @@ static inline void mem_cgroup_end_update_page_stat(struct page *page, { } +static inline bool mem_cgroup_toggle_oom(bool new) +{ + return false; +} + +static inline void mem_cgroup_enable_oom(void) +{ +} + +static inline void mem_cgroup_disable_oom(void) +{ +} + +static inline bool task_in_memcg_oom(struct task_struct *p) +{ + return false; +} + +static inline bool mem_cgroup_oom_synchronize(void) +{ + return false; +} + static inline void mem_cgroup_inc_page_stat(struct page *page, - enum mem_cgroup_page_stat_item idx) + enum mem_cgroup_stat_index idx) { } static inline void mem_cgroup_dec_page_stat(struct page *page, - enum mem_cgroup_page_stat_item idx) + enum mem_cgroup_stat_index idx) { } diff --git a/include/linux/memory.h b/include/linux/memory.h index 45e93b468878..9a6bbf76452d 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -18,22 +18,16 @@ #include <linux/node.h> #include <linux/compiler.h> #include <linux/mutex.h> +#include <linux/notifier.h> #define MIN_MEMORY_BLOCK_SIZE (1UL << SECTION_SIZE_BITS) struct memory_block { unsigned long start_section_nr; unsigned long end_section_nr; - unsigned long state; - int section_count; - - /* - * This serializes all state change requests. It isn't - * held during creation because the control files are - * created long after the critical areas during - * initialization. - */ - struct mutex state_mutex; + unsigned long state; /* serialized by the dev->lock */ + int section_count; /* serialized by mem_sysfs_mutex */ + int online_type; /* for passing data to online routine */ int phys_device; /* to which fru does this belong? */ void *hw; /* optional pointer to fw/hw data */ int (*phys_callback)(struct memory_block *); @@ -114,26 +108,31 @@ extern void unregister_memory_notifier(struct notifier_block *nb); extern int register_memory_isolate_notifier(struct notifier_block *nb); extern void unregister_memory_isolate_notifier(struct notifier_block *nb); extern int register_new_memory(int, struct mem_section *); +#ifdef CONFIG_MEMORY_HOTREMOVE extern int unregister_memory_section(struct mem_section *); +#endif extern int memory_dev_init(void); -extern int remove_memory_block(unsigned long, struct mem_section *, int); extern int memory_notify(unsigned long val, void *v); extern int memory_isolate_notify(unsigned long val, void *v); extern struct memory_block *find_memory_block_hinted(struct mem_section *, struct memory_block *); extern struct memory_block *find_memory_block(struct mem_section *); #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) -enum mem_add_context { BOOT, HOTPLUG }; #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ #ifdef CONFIG_MEMORY_HOTPLUG -#define hotplug_memory_notifier(fn, pri) { \ +#define hotplug_memory_notifier(fn, pri) ({ \ static __meminitdata struct notifier_block fn##_mem_nb =\ - { .notifier_call = fn, .priority = pri }; \ + { .notifier_call = fn, .priority = pri };\ register_memory_notifier(&fn##_mem_nb); \ -} +}) +#define register_hotmemory_notifier(nb) register_memory_notifier(nb) +#define unregister_hotmemory_notifier(nb) unregister_memory_notifier(nb) #else -#define hotplug_memory_notifier(fn, pri) do { } while (0) +#define hotplug_memory_notifier(fn, pri) ({ 0; }) +/* These aren't inline functions due to a GCC bug. */ +#define register_hotmemory_notifier(nb) ({ (void)(nb); 0; }) +#define unregister_hotmemory_notifier(nb) ({ (void)(nb); }) #endif /* diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index b6a3be7d47bf..dd38e62b84d2 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -97,13 +97,13 @@ extern void __online_page_free(struct page *page); #ifdef CONFIG_MEMORY_HOTREMOVE extern bool is_pageblock_removable_nolock(struct page *page); extern int arch_remove_memory(u64 start, u64 size); +extern int __remove_pages(struct zone *zone, unsigned long start_pfn, + unsigned long nr_pages); #endif /* CONFIG_MEMORY_HOTREMOVE */ /* reasonably generic interface to expand the physical pages in a zone */ extern int __add_pages(int nid, struct zone *zone, unsigned long start_pfn, unsigned long nr_pages); -extern int __remove_pages(struct zone *zone, unsigned long start_pfn, - unsigned long nr_pages); #ifdef CONFIG_NUMA extern int memory_add_physaddr_to_nid(u64 start); @@ -234,6 +234,8 @@ static inline void unlock_memory_hotplug(void) {} extern int is_mem_section_removable(unsigned long pfn, unsigned long nr_pages); extern void try_offline_node(int nid); +extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); +extern void remove_memory(int nid, u64 start, u64 size); #else static inline int is_mem_section_removable(unsigned long pfn, @@ -243,15 +245,23 @@ static inline int is_mem_section_removable(unsigned long pfn, } static inline void try_offline_node(int nid) {} + +static inline int offline_pages(unsigned long start_pfn, unsigned long nr_pages) +{ + return -EINVAL; +} + +static inline void remove_memory(int nid, u64 start, u64 size) {} #endif /* CONFIG_MEMORY_HOTREMOVE */ +extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, + void *arg, int (*func)(struct memory_block *, void *)); extern int mem_online_node(int nid); extern int add_memory(int nid, u64 start, u64 size); extern int arch_add_memory(int nid, u64 start, u64 size); extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); -extern int offline_memory_block(struct memory_block *mem); extern bool is_memblock_offlined(struct memory_block *mem); -extern int remove_memory(int nid, u64 start, u64 size); +extern void remove_memory(int nid, u64 start, u64 size); extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn, int nr_pages); extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms); diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 0d7df39a5885..da6716b9e3fe 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -91,7 +91,6 @@ static inline struct mempolicy *mpol_dup(struct mempolicy *pol) } #define vma_policy(vma) ((vma)->vm_policy) -#define vma_set_policy(vma, pol) ((vma)->vm_policy = (pol)) static inline void mpol_get(struct mempolicy *pol) { @@ -126,6 +125,7 @@ struct shared_policy { spinlock_t lock; }; +int vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst); void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol); int mpol_set_shared_policy(struct shared_policy *info, struct vm_area_struct *vma, @@ -173,7 +173,7 @@ extern int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol); /* Check if a vma is migratable */ static inline int vma_migratable(struct vm_area_struct *vma) { - if (vma->vm_flags & (VM_IO | VM_HUGETLB | VM_PFNMAP)) + if (vma->vm_flags & (VM_IO | VM_PFNMAP)) return 0; /* * Migration allocates pages in the highest zone. If we cannot @@ -240,7 +240,12 @@ mpol_shared_policy_lookup(struct shared_policy *sp, unsigned long idx) } #define vma_policy(vma) NULL -#define vma_set_policy(vma, pol) do {} while(0) + +static inline int +vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst) +{ + return 0; +} static inline void numa_policy_init(void) { diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h index e94537befabd..97cb283cc8e1 100644 --- a/include/linux/mfd/88pm80x.h +++ b/include/linux/mfd/88pm80x.h @@ -17,7 +17,6 @@ #include <linux/regmap.h> #include <linux/atomic.h> -#define PM80X_VERSION_MASK (0xFF) /* 80X chip ID mask */ enum { CHIP_INVALID = 0, CHIP_PM800, @@ -299,8 +298,7 @@ struct pm80x_chip { struct regmap *regmap; struct regmap_irq_chip *regmap_irq_chip; struct regmap_irq_chip_data *irq_data; - unsigned char version; - int id; + int type; int irq; int irq_mode; unsigned long wu_flag; @@ -309,8 +307,14 @@ struct pm80x_chip { struct pm80x_platform_data { struct pm80x_rtc_pdata *rtc; - unsigned short power_page_addr; /* power page I2C address */ - unsigned short gpadc_page_addr; /* gpadc page I2C address */ + /* + * For the regulator not defined, set regulators[not_defined] to be + * NULL. num_regulators are the number of regulators supposed to be + * initialized. If all regulators are not defined, set num_regulators + * to be 0. + */ + struct regulator_init_data *regulators[PM800_ID_RG_MAX]; + unsigned int num_regulators; int irq_mode; /* Clear interrupt by read/write(0/1) */ int batt_det; /* enable/disable */ int (*plat_config)(struct pm80x_chip *chip, @@ -363,7 +367,6 @@ static inline int pm80x_dev_resume(struct device *dev) } #endif -extern int pm80x_init(struct i2c_client *client, - const struct i2c_device_id *id); +extern int pm80x_init(struct i2c_client *client); extern int pm80x_deinit(void); #endif /* __LINUX_MFD_88PM80X_H */ diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h index 9ead60bc66b7..3301b2031c8d 100644 --- a/include/linux/mfd/abx500.h +++ b/include/linux/mfd/abx500.h @@ -89,6 +89,11 @@ struct abx500_fg; * points. * @maint_thres This is the threshold where we stop reporting * battery full while in maintenance, in per cent + * @pcut_enable: Enable power cut feature in ab8505 + * @pcut_max_time: Max time threshold + * @pcut_flag_time: Flagtime threshold + * @pcut_max_restart: Max number of restarts + * @pcut_debounce_time: Sets battery debounce time */ struct abx500_fg_parameters { int recovery_sleep_timer; @@ -106,6 +111,11 @@ struct abx500_fg_parameters { int battok_raising_th_sel1; int user_cap_limit; int maint_thres; + bool pcut_enable; + u8 pcut_max_time; + u8 pcut_flag_time; + u8 pcut_max_restart; + u8 pcut_debounce_time; }; /** @@ -173,11 +183,11 @@ struct abx500_battery_type { int low_high_vol_lvl; int battery_resistance; int n_temp_tbl_elements; - struct abx500_res_to_temp *r_to_t_tbl; + const struct abx500_res_to_temp *r_to_t_tbl; int n_v_cap_tbl_elements; - struct abx500_v_to_cap *v_to_cap_tbl; + const struct abx500_v_to_cap *v_to_cap_tbl; int n_batres_tbl_elements; - struct batres_vs_temp *batres_tbl; + const struct batres_vs_temp *batres_tbl; }; /** @@ -236,7 +246,11 @@ struct abx500_bm_charger_parameters { * @interval_not_charging charge alg cycle period time when not charging (sec) * @temp_hysteresis temperature hysteresis * @gnd_lift_resistance Battery ground to phone ground resistance (mOhm) - * @maxi: maximization parameters + * @n_chg_out_curr number of elements in array chg_output_curr + * @n_chg_in_curr number of elements in array chg_input_curr + * @chg_output_curr charger output current level map + * @chg_input_curr charger input current level map + * @maxi maximization parameters * @cap_levels capacity in percent for the different capacity levels * @bat_type table of supported battery types * @chg_params charger parameters @@ -257,6 +271,7 @@ struct abx500_bm_data { bool autopower_cfg; bool ac_enabled; bool usb_enabled; + bool usb_power_path; bool no_maintenance; bool capacity_scaling; bool chg_unknown_bat; @@ -270,6 +285,10 @@ struct abx500_bm_data { int interval_not_charging; int temp_hysteresis; int gnd_lift_resistance; + int n_chg_out_curr; + int n_chg_in_curr; + int *chg_output_curr; + int *chg_input_curr; const struct abx500_maxim_parameters *maxi; const struct abx500_bm_capacity_levels *cap_levels; struct abx500_battery_type *bat_type; diff --git a/include/linux/mfd/abx500/ab8500-bm.h b/include/linux/mfd/abx500/ab8500-bm.h index 8d35bfe164c8..cc892a8d8d6e 100644 --- a/include/linux/mfd/abx500/ab8500-bm.h +++ b/include/linux/mfd/abx500/ab8500-bm.h @@ -23,6 +23,7 @@ * Bank : 0x5 */ #define AB8500_USB_LINE_STAT_REG 0x80 +#define AB8500_USB_LINE_CTRL2_REG 0x82 #define AB8500_USB_LINK1_STAT_REG 0x94 /* @@ -33,7 +34,7 @@ #define AB8500_CH_STATUS2_REG 0x01 #define AB8500_CH_USBCH_STAT1_REG 0x02 #define AB8500_CH_USBCH_STAT2_REG 0x03 -#define AB8500_CH_FSM_STAT_REG 0x04 +#define AB8540_CH_USBCH_STAT3_REG 0x04 #define AB8500_CH_STAT_REG 0x05 /* @@ -69,6 +70,8 @@ #define AB8500_USBCH_CTRL1_REG 0xC0 #define AB8500_USBCH_CTRL2_REG 0xC1 #define AB8500_USBCH_IPT_CRNTLVL_REG 0xC2 +#define AB8540_USB_PP_MODE_REG 0xC5 +#define AB8540_USB_PP_CHR_REG 0xC6 /* * Gas Gauge register offsets @@ -105,6 +108,7 @@ #define AB8500_RTC_BACKUP_CHG_REG 0x0C #define AB8500_RTC_CC_CONF_REG 0x01 #define AB8500_RTC_CTRL_REG 0x0B +#define AB8500_RTC_CTRL1_REG 0x11 /* * OTP register offsets @@ -154,6 +158,7 @@ #define CH_OP_CUR_LVL_1P4 0x0D #define CH_OP_CUR_LVL_1P5 0x0E #define CH_OP_CUR_LVL_1P6 0x0F +#define CH_OP_CUR_LVL_2P 0x3F /* BTEMP High thermal limits */ #define BTEMP_HIGH_TH_57_0 0x00 @@ -179,10 +184,25 @@ #define BUP_ICH_SEL_300UA 0x08 #define BUP_ICH_SEL_700UA 0x0C -#define BUP_VCH_SEL_2P5V 0x00 -#define BUP_VCH_SEL_2P6V 0x01 -#define BUP_VCH_SEL_2P8V 0x02 -#define BUP_VCH_SEL_3P1V 0x03 +enum bup_vch_sel { + BUP_VCH_SEL_2P5V, + BUP_VCH_SEL_2P6V, + BUP_VCH_SEL_2P8V, + BUP_VCH_SEL_3P1V, + /* + * Note that the following 5 values 2.7v, 2.9v, 3.0v, 3.2v, 3.3v + * are only available on ab8540. You can't choose these 5 + * voltage on ab8500/ab8505/ab9540. + */ + BUP_VCH_SEL_2P7V, + BUP_VCH_SEL_2P9V, + BUP_VCH_SEL_3P0V, + BUP_VCH_SEL_3P2V, + BUP_VCH_SEL_3P3V, +}; + +#define BUP_VCH_RANGE 0x02 +#define VBUP33_VRTCN 0x01 /* Battery OVV constants */ #define BATT_OVV_ENA 0x02 @@ -228,6 +248,8 @@ #define BAT_CTRL_20U_ENA 0x02 #define BAT_CTRL_18U_ENA 0x01 #define BAT_CTRL_16U_ENA 0x02 +#define BAT_CTRL_60U_ENA 0x01 +#define BAT_CTRL_120U_ENA 0x02 #define BAT_CTRL_CMP_ENA 0x04 #define FORCE_BAT_CTRL_CMP_HIGH 0x08 #define BAT_CTRL_PULL_UP_ENA 0x10 @@ -235,6 +257,24 @@ /* Battery type */ #define BATTERY_UNKNOWN 00 +/* Registers for pcut feature in ab8505 and ab9540 */ +#define AB8505_RTC_PCUT_CTL_STATUS_REG 0x12 +#define AB8505_RTC_PCUT_TIME_REG 0x13 +#define AB8505_RTC_PCUT_MAX_TIME_REG 0x14 +#define AB8505_RTC_PCUT_FLAG_TIME_REG 0x15 +#define AB8505_RTC_PCUT_RESTART_REG 0x16 +#define AB8505_RTC_PCUT_DEBOUNCE_REG 0x17 + +/* USB Power Path constants for ab8540 */ +#define BUS_VSYS_VOL_SELECT_MASK 0x06 +#define BUS_VSYS_VOL_SELECT_3P6V 0x00 +#define BUS_VSYS_VOL_SELECT_3P325V 0x02 +#define BUS_VSYS_VOL_SELECT_3P9V 0x04 +#define BUS_VSYS_VOL_SELECT_4P3V 0x06 +#define BUS_POWER_PATH_MODE_ENA 0x01 +#define BUS_PP_PRECHG_CURRENT_MASK 0x0E +#define BUS_POWER_PATH_PRECHG_ENA 0x01 + /** * struct res_to_temp - defines one point in a temp to res curve. To * be used in battery packs that combines the identification resistor with a @@ -283,6 +323,11 @@ struct ab8500_fg; * points. * @maint_thres This is the threshold where we stop reporting * battery full while in maintenance, in per cent + * @pcut_enable: Enable power cut feature in ab8505 + * @pcut_max_time: Max time threshold + * @pcut_flag_time: Flagtime threshold + * @pcut_max_restart: Max number of restarts + * @pcut_debunce_time: Sets battery debounce time */ struct ab8500_fg_parameters { int recovery_sleep_timer; @@ -299,6 +344,11 @@ struct ab8500_fg_parameters { int battok_raising_th_sel1; int user_cap_limit; int maint_thres; + bool pcut_enable; + u8 pcut_max_time; + u8 pcut_flag_time; + u8 pcut_max_restart; + u8 pcut_debunce_time; }; /** @@ -415,6 +465,7 @@ void ab8500_fg_reinit(void); void ab8500_charger_usb_state_changed(u8 bm_usb_state, u16 mA); struct ab8500_btemp *ab8500_btemp_get(void); int ab8500_btemp_get_batctrl_temp(struct ab8500_btemp *btemp); +int ab8500_btemp_get_temp(struct ab8500_btemp *btemp); struct ab8500_fg *ab8500_fg_get(void); int ab8500_fg_inst_curr_blocking(struct ab8500_fg *dev); int ab8500_fg_inst_curr_start(struct ab8500_fg *di); diff --git a/include/linux/mfd/abx500/ab8500-gpadc.h b/include/linux/mfd/abx500/ab8500-gpadc.h index 252966769d93..49ded001049b 100644 --- a/include/linux/mfd/abx500/ab8500-gpadc.h +++ b/include/linux/mfd/abx500/ab8500-gpadc.h @@ -4,32 +4,72 @@ * * Author: Arun R Murthy <arun.murthy@stericsson.com> * Author: Daniel Willerud <daniel.willerud@stericsson.com> + * Author: M'boumba Cedric Madianga <cedric.madianga@stericsson.com> */ #ifndef _AB8500_GPADC_H #define _AB8500_GPADC_H -/* GPADC source: From datasheet(ADCSwSel[4:0] in GPADCCtrl2) */ -#define BAT_CTRL 0x01 -#define BTEMP_BALL 0x02 -#define MAIN_CHARGER_V 0x03 -#define ACC_DETECT1 0x04 -#define ACC_DETECT2 0x05 -#define ADC_AUX1 0x06 -#define ADC_AUX2 0x07 -#define MAIN_BAT_V 0x08 -#define VBUS_V 0x09 -#define MAIN_CHARGER_C 0x0A -#define USB_CHARGER_C 0x0B -#define BK_BAT_V 0x0C -#define DIE_TEMP 0x0D +/* GPADC source: From datasheet(ADCSwSel[4:0] in GPADCCtrl2 + * and ADCHwSel[4:0] in GPADCCtrl3 ) */ +#define BAT_CTRL 0x01 +#define BTEMP_BALL 0x02 +#define MAIN_CHARGER_V 0x03 +#define ACC_DETECT1 0x04 +#define ACC_DETECT2 0x05 +#define ADC_AUX1 0x06 +#define ADC_AUX2 0x07 +#define MAIN_BAT_V 0x08 +#define VBUS_V 0x09 +#define MAIN_CHARGER_C 0x0A +#define USB_CHARGER_C 0x0B +#define BK_BAT_V 0x0C +#define DIE_TEMP 0x0D +#define USB_ID 0x0E +#define XTAL_TEMP 0x12 +#define VBAT_TRUE_MEAS 0x13 +#define BAT_CTRL_AND_IBAT 0x1C +#define VBAT_MEAS_AND_IBAT 0x1D +#define VBAT_TRUE_MEAS_AND_IBAT 0x1E +#define BAT_TEMP_AND_IBAT 0x1F + +/* Virtual channel used only for ibat convertion to ampere + * Battery current conversion (ibat) cannot be requested as a single conversion + * but it is always in combination with other input requests + */ +#define IBAT_VIRTUAL_CHANNEL 0xFF + +#define SAMPLE_1 1 +#define SAMPLE_4 4 +#define SAMPLE_8 8 +#define SAMPLE_16 16 +#define RISING_EDGE 0 +#define FALLING_EDGE 1 + +/* Arbitrary ADC conversion type constants */ +#define ADC_SW 0 +#define ADC_HW 1 struct ab8500_gpadc; struct ab8500_gpadc *ab8500_gpadc_get(char *name); -int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel); -int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel); +int ab8500_gpadc_sw_hw_convert(struct ab8500_gpadc *gpadc, u8 channel, + u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type); +static inline int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 channel) +{ + return ab8500_gpadc_sw_hw_convert(gpadc, channel, + SAMPLE_16, 0, 0, ADC_SW); +} + +int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel, + u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type); +int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel, + u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type, + int *ibat); int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, - u8 channel, int ad_value); + u8 channel, int ad_value); +void ab8540_gpadc_get_otp(struct ab8500_gpadc *gpadc, + u16 *vmain_l, u16 *vmain_h, u16 *btemp_l, u16 *btemp_h, + u16 *vbat_l, u16 *vbat_h, u16 *ibat_l, u16 *ibat_h); #endif /* _AB8500_GPADC_H */ diff --git a/include/linux/mfd/abx500/ab8500-sysctrl.h b/include/linux/mfd/abx500/ab8500-sysctrl.h index ebf12e793db9..adba89d9c660 100644 --- a/include/linux/mfd/abx500/ab8500-sysctrl.h +++ b/include/linux/mfd/abx500/ab8500-sysctrl.h @@ -12,6 +12,7 @@ int ab8500_sysctrl_read(u16 reg, u8 *value); int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value); +void ab8500_restart(char mode, const char *cmd); #else @@ -40,6 +41,7 @@ static inline int ab8500_sysctrl_clear(u16 reg, u8 bits) /* Configuration data for SysClkReq1RfClkBuf - SysClkReq8RfClkBuf */ struct ab8500_sysctrl_platform_data { u8 initial_req_buf_config[8]; + u16 (*reboot_reason_code)(const char *cmd); }; /* Registers */ @@ -276,8 +278,8 @@ struct ab8500_sysctrl_platform_data { #define AB9540_SYSCLK12CONFCTRL_PLL26TO38ENA BIT(0) #define AB9540_SYSCLK12CONFCTRL_SYSCLK12USBMUXSEL BIT(1) -#define AB9540_SYSCLK12CONFCTRL_INT384MHZMUXSEL_MASK 0x0C -#define AB9540_SYSCLK12CONFCTRL_INT384MHZMUXSEL_SHIFT 2 +#define AB9540_SYSCLK12CONFCTRL_INT384MHZMUXSEL0 BIT(2) +#define AB9540_SYSCLK12CONFCTRL_INT384MHZMUXSEL1 BIT(3) #define AB9540_SYSCLK12CONFCTRL_SYSCLK12BUFMUX BIT(4) #define AB9540_SYSCLK12CONFCTRL_SYSCLK12PLLMUX BIT(5) #define AB9540_SYSCLK12CONFCTRL_SYSCLK2MUXVALID BIT(6) @@ -299,4 +301,8 @@ struct ab8500_sysctrl_platform_data { #define AB9540_SYSCLK12BUF4VALID_SYSCLK12BUF4VALID_MASK 0xFF #define AB9540_SYSCLK12BUF4VALID_SYSCLK12BUF4VALID_SHIFT 0 +#define AB8500_ENABLE_WD 0x1 +#define AB8500_KICK_WD 0x2 +#define AB8500_WD_RESTART_ON_EXPIRE 0x10 + #endif /* __AB8500_SYSCTRL_H */ diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h index 9db0bda446a0..f4acd898dac9 100644 --- a/include/linux/mfd/abx500/ab8500.h +++ b/include/linux/mfd/abx500/ab8500.h @@ -291,6 +291,8 @@ enum ab8500_version { #define AB8540_INT_FSYNC2R 213 #define AB8540_INT_BITCLK2F 214 #define AB8540_INT_BITCLK2R 215 +/* ab8540_irq_regoffset[27] -> IT[Source|Latch|Mask]33 */ +#define AB8540_INT_RTC_1S 216 /* * AB8500_AB9540_NR_IRQS is used when configuring the IRQ numbers for the @@ -362,10 +364,10 @@ struct ab8500 { u8 *oldmask; int mask_size; const int *irq_reg_offset; + int it_latchhier_num; }; -struct regulator_reg_init; -struct regulator_init_data; +struct ab8500_regulator_platform_data; struct ab8500_gpio_platform_data; struct ab8500_codec_platform_data; struct ab8500_sysctrl_platform_data; @@ -373,21 +375,13 @@ struct ab8500_sysctrl_platform_data; /** * struct ab8500_platform_data - AB8500 platform data * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used - * @pm_power_off: Should machine pm power off hook be registered or not * @init: board-specific initialization after detection of ab8500 - * @num_regulator_reg_init: number of regulator init registers - * @regulator_reg_init: regulator init registers - * @num_regulator: number of regulators * @regulator: machine-specific constraints for regulators */ struct ab8500_platform_data { int irq_base; - bool pm_power_off; void (*init) (struct ab8500 *); - int num_regulator_reg_init; - struct ab8500_regulator_reg_init *regulator_reg_init; - int num_regulator; - struct regulator_init_data *regulator; + struct ab8500_regulator_platform_data *regulator; struct abx500_gpio_platform_data *gpio; struct ab8500_codec_platform_data *codec; struct ab8500_sysctrl_platform_data *sysctrl; @@ -512,6 +506,8 @@ static inline int is_ab9540_2p0_or_earlier(struct ab8500 *ab) return (is_ab9540(ab) && (ab->chip_id < AB8500_CUT2P0)); } +void ab8500_override_turn_on_stat(u8 mask, u8 set); + #ifdef CONFIG_AB8500_DEBUG void ab8500_dump_all_banks(struct device *dev); void ab8500_debug_register_interrupt(int line); diff --git a/include/linux/mfd/abx500/ux500_chargalg.h b/include/linux/mfd/abx500/ux500_chargalg.h index d43ac0f35526..234c99143bf7 100644 --- a/include/linux/mfd/abx500/ux500_chargalg.h +++ b/include/linux/mfd/abx500/ux500_chargalg.h @@ -17,8 +17,11 @@ struct ux500_charger; struct ux500_charger_ops { int (*enable) (struct ux500_charger *, int, int, int); + int (*check_enable) (struct ux500_charger *, int, int); int (*kick_wd) (struct ux500_charger *); int (*update_curr) (struct ux500_charger *, int); + int (*pp_enable) (struct ux500_charger *, bool); + int (*pre_chg_enable) (struct ux500_charger *, bool); }; /** @@ -29,6 +32,7 @@ struct ux500_charger_ops { * @max_out_curr maximum output charger current in mA * @enabled indicates if this charger is used or not * @external external charger unit (pm2xxx) + * @power_path USB power path support */ struct ux500_charger { struct power_supply psy; @@ -38,6 +42,9 @@ struct ux500_charger { int wdt_refresh; bool enabled; bool external; + bool power_path; }; +extern struct blocking_notifier_head charger_notifier_list; + #endif diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h index a710255528d7..5cf8b91ce996 100644 --- a/include/linux/mfd/arizona/core.h +++ b/include/linux/mfd/arizona/core.h @@ -23,6 +23,7 @@ enum arizona_type { WM5102 = 1, WM5110 = 2, + WM8997 = 3, }; #define ARIZONA_IRQ_GP1 0 @@ -95,11 +96,16 @@ struct arizona { struct arizona_pdata pdata; + unsigned int external_dcvdd:1; + int irq; struct irq_domain *virq; struct regmap_irq_chip_data *aod_irq_chip; struct regmap_irq_chip_data *irq_chip; + bool hpdet_magic; + unsigned int hp_ena; + struct mutex clk_lock; int clk32k_ref; @@ -116,5 +122,6 @@ int arizona_set_irq_wake(struct arizona *arizona, int irq, int on); int wm5102_patch(struct arizona *arizona); int wm5110_patch(struct arizona *arizona); +int wm8997_patch(struct arizona *arizona); #endif diff --git a/include/linux/mfd/arizona/gpio.h b/include/linux/mfd/arizona/gpio.h new file mode 100644 index 000000000000..d2146bb74f89 --- /dev/null +++ b/include/linux/mfd/arizona/gpio.h @@ -0,0 +1,96 @@ +/* + * GPIO configuration for Arizona devices + * + * Copyright 2013 Wolfson Microelectronics. PLC. + * + * Author: Charles Keepax <ckeepax@opensource.wolfsonmicro.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 _ARIZONA_GPIO_H +#define _ARIZONA_GPIO_H + +#define ARIZONA_GP_FN_TXLRCLK 0x00 +#define ARIZONA_GP_FN_GPIO 0x01 +#define ARIZONA_GP_FN_IRQ1 0x02 +#define ARIZONA_GP_FN_IRQ2 0x03 +#define ARIZONA_GP_FN_OPCLK 0x04 +#define ARIZONA_GP_FN_FLL1_OUT 0x05 +#define ARIZONA_GP_FN_FLL2_OUT 0x06 +#define ARIZONA_GP_FN_PWM1 0x08 +#define ARIZONA_GP_FN_PWM2 0x09 +#define ARIZONA_GP_FN_SYSCLK_UNDERCLOCKED 0x0A +#define ARIZONA_GP_FN_ASYNCCLK_UNDERCLOCKED 0x0B +#define ARIZONA_GP_FN_FLL1_LOCK 0x0C +#define ARIZONA_GP_FN_FLL2_LOCK 0x0D +#define ARIZONA_GP_FN_FLL1_CLOCK_OK 0x0F +#define ARIZONA_GP_FN_FLL2_CLOCK_OK 0x10 +#define ARIZONA_GP_FN_HEADPHONE_DET 0x12 +#define ARIZONA_GP_FN_MIC_DET 0x13 +#define ARIZONA_GP_FN_WSEQ_STATUS 0x15 +#define ARIZONA_GP_FN_CIF_ADDRESS_ERROR 0x16 +#define ARIZONA_GP_FN_ASRC1_LOCK 0x1A +#define ARIZONA_GP_FN_ASRC2_LOCK 0x1B +#define ARIZONA_GP_FN_ASRC_CONFIG_ERROR 0x1C +#define ARIZONA_GP_FN_DRC1_SIGNAL_DETECT 0x1D +#define ARIZONA_GP_FN_DRC1_ANTICLIP 0x1E +#define ARIZONA_GP_FN_DRC1_DECAY 0x1F +#define ARIZONA_GP_FN_DRC1_NOISE 0x20 +#define ARIZONA_GP_FN_DRC1_QUICK_RELEASE 0x21 +#define ARIZONA_GP_FN_DRC2_SIGNAL_DETECT 0x22 +#define ARIZONA_GP_FN_DRC2_ANTICLIP 0x23 +#define ARIZONA_GP_FN_DRC2_DECAY 0x24 +#define ARIZONA_GP_FN_DRC2_NOISE 0x25 +#define ARIZONA_GP_FN_DRC2_QUICK_RELEASE 0x26 +#define ARIZONA_GP_FN_MIXER_DROPPED_SAMPLE 0x27 +#define ARIZONA_GP_FN_AIF1_CONFIG_ERROR 0x28 +#define ARIZONA_GP_FN_AIF2_CONFIG_ERROR 0x29 +#define ARIZONA_GP_FN_AIF3_CONFIG_ERROR 0x2A +#define ARIZONA_GP_FN_SPK_TEMP_SHUTDOWN 0x2B +#define ARIZONA_GP_FN_SPK_TEMP_WARNING 0x2C +#define ARIZONA_GP_FN_UNDERCLOCKED 0x2D +#define ARIZONA_GP_FN_OVERCLOCKED 0x2E +#define ARIZONA_GP_FN_DSP_IRQ1 0x35 +#define ARIZONA_GP_FN_DSP_IRQ2 0x36 +#define ARIZONA_GP_FN_ASYNC_OPCLK 0x3D +#define ARIZONA_GP_FN_BOOT_DONE 0x44 +#define ARIZONA_GP_FN_DSP1_RAM_READY 0x45 +#define ARIZONA_GP_FN_SYSCLK_ENA_STATUS 0x4B +#define ARIZONA_GP_FN_ASYNCCLK_ENA_STATUS 0x4C + +#define ARIZONA_GPN_DIR 0x8000 /* GPN_DIR */ +#define ARIZONA_GPN_DIR_MASK 0x8000 /* GPN_DIR */ +#define ARIZONA_GPN_DIR_SHIFT 15 /* GPN_DIR */ +#define ARIZONA_GPN_DIR_WIDTH 1 /* GPN_DIR */ +#define ARIZONA_GPN_PU 0x4000 /* GPN_PU */ +#define ARIZONA_GPN_PU_MASK 0x4000 /* GPN_PU */ +#define ARIZONA_GPN_PU_SHIFT 14 /* GPN_PU */ +#define ARIZONA_GPN_PU_WIDTH 1 /* GPN_PU */ +#define ARIZONA_GPN_PD 0x2000 /* GPN_PD */ +#define ARIZONA_GPN_PD_MASK 0x2000 /* GPN_PD */ +#define ARIZONA_GPN_PD_SHIFT 13 /* GPN_PD */ +#define ARIZONA_GPN_PD_WIDTH 1 /* GPN_PD */ +#define ARIZONA_GPN_LVL 0x0800 /* GPN_LVL */ +#define ARIZONA_GPN_LVL_MASK 0x0800 /* GPN_LVL */ +#define ARIZONA_GPN_LVL_SHIFT 11 /* GPN_LVL */ +#define ARIZONA_GPN_LVL_WIDTH 1 /* GPN_LVL */ +#define ARIZONA_GPN_POL 0x0400 /* GPN_POL */ +#define ARIZONA_GPN_POL_MASK 0x0400 /* GPN_POL */ +#define ARIZONA_GPN_POL_SHIFT 10 /* GPN_POL */ +#define ARIZONA_GPN_POL_WIDTH 1 /* GPN_POL */ +#define ARIZONA_GPN_OP_CFG 0x0200 /* GPN_OP_CFG */ +#define ARIZONA_GPN_OP_CFG_MASK 0x0200 /* GPN_OP_CFG */ +#define ARIZONA_GPN_OP_CFG_SHIFT 9 /* GPN_OP_CFG */ +#define ARIZONA_GPN_OP_CFG_WIDTH 1 /* GPN_OP_CFG */ +#define ARIZONA_GPN_DB 0x0100 /* GPN_DB */ +#define ARIZONA_GPN_DB_MASK 0x0100 /* GPN_DB */ +#define ARIZONA_GPN_DB_SHIFT 8 /* GPN_DB */ +#define ARIZONA_GPN_DB_WIDTH 1 /* GPN_DB */ +#define ARIZONA_GPN_FN_MASK 0x007F /* GPN_DB */ +#define ARIZONA_GPN_FN_SHIFT 0 /* GPN_DB */ +#define ARIZONA_GPN_FN_WIDTH 7 /* GPN_DB */ + +#endif diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 455c51d22d6b..12a5c135c746 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -77,7 +77,8 @@ struct arizona_micbias { int mV; /** Regulated voltage */ unsigned int ext_cap:1; /** External capacitor fitted */ unsigned int discharge:1; /** Actively discharge */ - unsigned int fast_start:1; /** Enable aggressive startup ramp rate */ + unsigned int soft_start:1; /** Disable aggressive startup ramp rate */ + unsigned int bypass:1; /** Use bypass mode */ }; struct arizona_micd_config { @@ -86,6 +87,11 @@ struct arizona_micd_config { bool gpio; }; +struct arizona_micd_range { + int max; /** Ohms */ + int key; /** Key to report to input layer */ +}; + struct arizona_pdata { int reset; /** GPIO controlling /RESET, if any */ int ldoena; /** GPIO controlling LODENA, if any */ @@ -99,7 +105,8 @@ struct arizona_pdata { /** If a direct 32kHz clock is provided on an MCLK specify it here */ int clk32k_src; - bool irq_active_high; /** IRQ polarity */ + /** Mode for primary IRQ (defaults to active low) */ + unsigned int irq_flags; /* Base GPIO */ int gpio_base; @@ -117,12 +124,21 @@ struct arizona_pdata { /** GPIO5 is used for jack detection */ bool jd_gpio5; + /** Internal pull on GPIO5 is disabled when used for jack detection */ + bool jd_gpio5_nopull; + /** Use the headphone detect circuit to identify the accessory */ bool hpdet_acc_id; + /** Check for line output with HPDET method */ + bool hpdet_acc_id_line; + /** GPIO used for mic isolation with HPDET */ int hpdet_id_gpio; + /** Extra debounce timeout used during initial mic detection (ms) */ + int micd_detect_debounce; + /** GPIO for mic detection polarity */ int micd_pol_gpio; @@ -135,9 +151,16 @@ struct arizona_pdata { /** Mic detect debounce level */ int micd_dbtime; + /** Mic detect timeout (ms) */ + int micd_timeout; + /** Force MICBIAS on for mic detect */ bool micd_force_micbias; + /** Mic detect level parameters */ + const struct arizona_micd_range *micd_ranges; + int num_micd_ranges; + /** Headset polarity configurations */ struct arizona_micd_config *micd_configs; int num_micd_configs; @@ -162,6 +185,9 @@ struct arizona_pdata { /** Haptic actuator type */ unsigned int hap_act; + + /** GPIO for primary IRQ (used for edge triggered emulation) */ + int irq_gpio; }; #endif diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h index 340355136069..cb49417f8ba9 100644 --- a/include/linux/mfd/arizona/registers.h +++ b/include/linux/mfd/arizona/registers.h @@ -85,12 +85,14 @@ #define ARIZONA_FLL1_CONTROL_6 0x176 #define ARIZONA_FLL1_LOOP_FILTER_TEST_1 0x177 #define ARIZONA_FLL1_NCO_TEST_0 0x178 +#define ARIZONA_FLL1_CONTROL_7 0x179 #define ARIZONA_FLL1_SYNCHRONISER_1 0x181 #define ARIZONA_FLL1_SYNCHRONISER_2 0x182 #define ARIZONA_FLL1_SYNCHRONISER_3 0x183 #define ARIZONA_FLL1_SYNCHRONISER_4 0x184 #define ARIZONA_FLL1_SYNCHRONISER_5 0x185 #define ARIZONA_FLL1_SYNCHRONISER_6 0x186 +#define ARIZONA_FLL1_SYNCHRONISER_7 0x187 #define ARIZONA_FLL1_SPREAD_SPECTRUM 0x189 #define ARIZONA_FLL1_GPIO_CLOCK 0x18A #define ARIZONA_FLL2_CONTROL_1 0x191 @@ -101,12 +103,14 @@ #define ARIZONA_FLL2_CONTROL_6 0x196 #define ARIZONA_FLL2_LOOP_FILTER_TEST_1 0x197 #define ARIZONA_FLL2_NCO_TEST_0 0x198 +#define ARIZONA_FLL2_CONTROL_7 0x199 #define ARIZONA_FLL2_SYNCHRONISER_1 0x1A1 #define ARIZONA_FLL2_SYNCHRONISER_2 0x1A2 #define ARIZONA_FLL2_SYNCHRONISER_3 0x1A3 #define ARIZONA_FLL2_SYNCHRONISER_4 0x1A4 #define ARIZONA_FLL2_SYNCHRONISER_5 0x1A5 #define ARIZONA_FLL2_SYNCHRONISER_6 0x1A6 +#define ARIZONA_FLL2_SYNCHRONISER_7 0x1A7 #define ARIZONA_FLL2_SPREAD_SPECTRUM 0x1A9 #define ARIZONA_FLL2_GPIO_CLOCK 0x1AA #define ARIZONA_MIC_CHARGE_PUMP_1 0x200 @@ -124,6 +128,10 @@ #define ARIZONA_MIC_DETECT_1 0x2A3 #define ARIZONA_MIC_DETECT_2 0x2A4 #define ARIZONA_MIC_DETECT_3 0x2A5 +#define ARIZONA_MIC_DETECT_LEVEL_1 0x2A6 +#define ARIZONA_MIC_DETECT_LEVEL_2 0x2A7 +#define ARIZONA_MIC_DETECT_LEVEL_3 0x2A8 +#define ARIZONA_MIC_DETECT_LEVEL_4 0x2A9 #define ARIZONA_MIC_NOISE_MIX_CONTROL_1 0x2C3 #define ARIZONA_ISOLATION_CONTROL 0x2CB #define ARIZONA_JACK_DETECT_ANALOGUE 0x2D3 @@ -207,12 +215,17 @@ #define ARIZONA_DAC_DIGITAL_VOLUME_6R 0x43D #define ARIZONA_DAC_VOLUME_LIMIT_6R 0x43E #define ARIZONA_NOISE_GATE_SELECT_6R 0x43F +#define ARIZONA_DRE_ENABLE 0x440 +#define ARIZONA_DRE_CONTROL_2 0x442 +#define ARIZONA_DRE_CONTROL_3 0x443 #define ARIZONA_DAC_AEC_CONTROL_1 0x450 #define ARIZONA_NOISE_GATE_CONTROL 0x458 #define ARIZONA_PDM_SPK1_CTRL_1 0x490 #define ARIZONA_PDM_SPK1_CTRL_2 0x491 #define ARIZONA_PDM_SPK2_CTRL_1 0x492 #define ARIZONA_PDM_SPK2_CTRL_2 0x493 +#define ARIZONA_SPK_CTRL_2 0x4B5 +#define ARIZONA_SPK_CTRL_3 0x4B6 #define ARIZONA_DAC_COMP_1 0x4DC #define ARIZONA_DAC_COMP_2 0x4DD #define ARIZONA_DAC_COMP_3 0x4DE @@ -992,6 +1005,7 @@ #define ARIZONA_DSP2_CLOCKING_1 0x1201 #define ARIZONA_DSP2_STATUS_1 0x1204 #define ARIZONA_DSP2_STATUS_2 0x1205 +#define ARIZONA_DSP2_STATUS_3 0x1206 #define ARIZONA_DSP2_SCRATCH_0 0x1240 #define ARIZONA_DSP2_SCRATCH_1 0x1241 #define ARIZONA_DSP2_SCRATCH_2 0x1242 @@ -1000,6 +1014,7 @@ #define ARIZONA_DSP3_CLOCKING_1 0x1301 #define ARIZONA_DSP3_STATUS_1 0x1304 #define ARIZONA_DSP3_STATUS_2 0x1305 +#define ARIZONA_DSP3_STATUS_3 0x1306 #define ARIZONA_DSP3_SCRATCH_0 0x1340 #define ARIZONA_DSP3_SCRATCH_1 0x1341 #define ARIZONA_DSP3_SCRATCH_2 0x1342 @@ -1008,6 +1023,7 @@ #define ARIZONA_DSP4_CLOCKING_1 0x1401 #define ARIZONA_DSP4_STATUS_1 0x1404 #define ARIZONA_DSP4_STATUS_2 0x1405 +#define ARIZONA_DSP4_STATUS_3 0x1406 #define ARIZONA_DSP4_SCRATCH_0 0x1440 #define ARIZONA_DSP4_SCRATCH_1 0x1441 #define ARIZONA_DSP4_SCRATCH_2 0x1442 @@ -1678,6 +1694,13 @@ #define ARIZONA_FLL1_FRC_INTEG_VAL_WIDTH 12 /* FLL1_FRC_INTEG_VAL - [11:0] */ /* + * R377 (0x179) - FLL1 Control 7 + */ +#define ARIZONA_FLL1_GAIN_MASK 0x003c /* FLL1_GAIN */ +#define ARIZONA_FLL1_GAIN_SHIFT 2 /* FLL1_GAIN */ +#define ARIZONA_FLL1_GAIN_WIDTH 4 /* FLL1_GAIN */ + +/* * R385 (0x181) - FLL1 Synchroniser 1 */ #define ARIZONA_FLL1_SYNC_ENA 0x0001 /* FLL1_SYNC_ENA */ @@ -1724,6 +1747,17 @@ #define ARIZONA_FLL1_CLK_SYNC_SRC_WIDTH 4 /* FLL1_CLK_SYNC_SRC - [3:0] */ /* + * R391 (0x187) - FLL1 Synchroniser 7 + */ +#define ARIZONA_FLL1_SYNC_GAIN_MASK 0x003c /* FLL1_SYNC_GAIN */ +#define ARIZONA_FLL1_SYNC_GAIN_SHIFT 2 /* FLL1_SYNC_GAIN */ +#define ARIZONA_FLL1_SYNC_GAIN_WIDTH 4 /* FLL1_SYNC_GAIN */ +#define ARIZONA_FLL1_SYNC_BW 0x0001 /* FLL1_SYNC_BW */ +#define ARIZONA_FLL1_SYNC_BW_MASK 0x0001 /* FLL1_SYNC_BW */ +#define ARIZONA_FLL1_SYNC_BW_SHIFT 0 /* FLL1_SYNC_BW */ +#define ARIZONA_FLL1_SYNC_BW_WIDTH 1 /* FLL1_SYNC_BW */ + +/* * R393 (0x189) - FLL1 Spread Spectrum */ #define ARIZONA_FLL1_SS_AMPL_MASK 0x0030 /* FLL1_SS_AMPL - [5:4] */ @@ -1816,6 +1850,13 @@ #define ARIZONA_FLL2_FRC_INTEG_VAL_WIDTH 12 /* FLL2_FRC_INTEG_VAL - [11:0] */ /* + * R409 (0x199) - FLL2 Control 7 + */ +#define ARIZONA_FLL2_GAIN_MASK 0x003c /* FLL2_GAIN */ +#define ARIZONA_FLL2_GAIN_SHIFT 2 /* FLL2_GAIN */ +#define ARIZONA_FLL2_GAIN_WIDTH 4 /* FLL2_GAIN */ + +/* * R417 (0x1A1) - FLL2 Synchroniser 1 */ #define ARIZONA_FLL2_SYNC_ENA 0x0001 /* FLL2_SYNC_ENA */ @@ -1862,6 +1903,17 @@ #define ARIZONA_FLL2_CLK_SYNC_SRC_WIDTH 4 /* FLL2_CLK_SYNC_SRC - [3:0] */ /* + * R423 (0x1A7) - FLL2 Synchroniser 7 + */ +#define ARIZONA_FLL2_SYNC_GAIN_MASK 0x003c /* FLL2_SYNC_GAIN */ +#define ARIZONA_FLL2_SYNC_GAIN_SHIFT 2 /* FLL2_SYNC_GAIN */ +#define ARIZONA_FLL2_SYNC_GAIN_WIDTH 4 /* FLL2_SYNC_GAIN */ +#define ARIZONA_FLL2_SYNC_BW 0x0001 /* FLL2_SYNC_BW */ +#define ARIZONA_FLL2_SYNC_BW_MASK 0x0001 /* FLL2_SYNC_BW */ +#define ARIZONA_FLL2_SYNC_BW_SHIFT 0 /* FLL2_SYNC_BW */ +#define ARIZONA_FLL2_SYNC_BW_WIDTH 1 /* FLL2_SYNC_BW */ + +/* * R425 (0x1A9) - FLL2 Spread Spectrum */ #define ARIZONA_FLL2_SS_AMPL_MASK 0x0030 /* FLL2_SS_AMPL - [5:4] */ @@ -3084,6 +3136,47 @@ #define ARIZONA_OUT6R_NGATE_SRC_WIDTH 12 /* OUT6R_NGATE_SRC - [11:0] */ /* + * R1088 (0x440) - DRE Enable + */ +#define ARIZONA_DRE3L_ENA 0x0010 /* DRE3L_ENA */ +#define ARIZONA_DRE3L_ENA_MASK 0x0010 /* DRE3L_ENA */ +#define ARIZONA_DRE3L_ENA_SHIFT 4 /* DRE3L_ENA */ +#define ARIZONA_DRE3L_ENA_WIDTH 1 /* DRE3L_ENA */ +#define ARIZONA_DRE2R_ENA 0x0008 /* DRE2R_ENA */ +#define ARIZONA_DRE2R_ENA_MASK 0x0008 /* DRE2R_ENA */ +#define ARIZONA_DRE2R_ENA_SHIFT 3 /* DRE2R_ENA */ +#define ARIZONA_DRE2R_ENA_WIDTH 1 /* DRE2R_ENA */ +#define ARIZONA_DRE2L_ENA 0x0004 /* DRE2L_ENA */ +#define ARIZONA_DRE2L_ENA_MASK 0x0004 /* DRE2L_ENA */ +#define ARIZONA_DRE2L_ENA_SHIFT 2 /* DRE2L_ENA */ +#define ARIZONA_DRE2L_ENA_WIDTH 1 /* DRE2L_ENA */ +#define ARIZONA_DRE1R_ENA 0x0002 /* DRE1R_ENA */ +#define ARIZONA_DRE1R_ENA_MASK 0x0002 /* DRE1R_ENA */ +#define ARIZONA_DRE1R_ENA_SHIFT 1 /* DRE1R_ENA */ +#define ARIZONA_DRE1R_ENA_WIDTH 1 /* DRE1R_ENA */ +#define ARIZONA_DRE1L_ENA 0x0001 /* DRE1L_ENA */ +#define ARIZONA_DRE1L_ENA_MASK 0x0001 /* DRE1L_ENA */ +#define ARIZONA_DRE1L_ENA_SHIFT 0 /* DRE1L_ENA */ +#define ARIZONA_DRE1L_ENA_WIDTH 1 /* DRE1L_ENA */ + +/* + * R1090 (0x442) - DRE Control 2 + */ +#define ARIZONA_DRE_T_LOW_MASK 0x3F00 /* DRE_T_LOW - [13:8] */ +#define ARIZONA_DRE_T_LOW_SHIFT 8 /* DRE_T_LOW - [13:8] */ +#define ARIZONA_DRE_T_LOW_WIDTH 6 /* DRE_T_LOW - [13:8] */ + +/* + * R1091 (0x443) - DRE Control 3 + */ +#define ARIZONA_DRE_GAIN_SHIFT_MASK 0xC000 /* DRE_GAIN_SHIFT - [15:14] */ +#define ARIZONA_DRE_GAIN_SHIFT_SHIFT 14 /* DRE_GAIN_SHIFT - [15:14] */ +#define ARIZONA_DRE_GAIN_SHIFT_WIDTH 2 /* DRE_GAIN_SHIFT - [15:14] */ +#define ARIZONA_DRE_LOW_LEVEL_ABS_MASK 0x000F /* LOW_LEVEL_ABS - [3:0] */ +#define ARIZONA_DRE_LOW_LEVEL_ABS_SHIFT 0 /* LOW_LEVEL_ABS - [3:0] */ +#define ARIZONA_DRE_LOW_LEVEL_ABS_WIDTH 4 /* LOW_LEVEL_ABS - [3:0] */ + +/* * R1104 (0x450) - DAC AEC Control 1 */ #define ARIZONA_AEC_LOOPBACK_SRC_MASK 0x003C /* AEC_LOOPBACK_SRC - [5:2] */ diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h new file mode 100644 index 000000000000..032af7fc5b2e --- /dev/null +++ b/include/linux/mfd/cros_ec.h @@ -0,0 +1,170 @@ +/* + * ChromeOS EC multi-function device + * + * Copyright (C) 2012 Google, Inc + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __LINUX_MFD_CROS_EC_H +#define __LINUX_MFD_CROS_EC_H + +#include <linux/mfd/cros_ec_commands.h> + +/* + * Command interface between EC and AP, for LPC, I2C and SPI interfaces. + */ +enum { + EC_MSG_TX_HEADER_BYTES = 3, + EC_MSG_TX_TRAILER_BYTES = 1, + EC_MSG_TX_PROTO_BYTES = EC_MSG_TX_HEADER_BYTES + + EC_MSG_TX_TRAILER_BYTES, + EC_MSG_RX_PROTO_BYTES = 3, + + /* Max length of messages */ + EC_MSG_BYTES = EC_HOST_PARAM_SIZE + EC_MSG_TX_PROTO_BYTES, + +}; + +/** + * struct cros_ec_msg - A message sent to the EC, and its reply + * + * @version: Command version number (often 0) + * @cmd: Command to send (EC_CMD_...) + * @out_buf: Outgoing payload (to EC) + * @outlen: Outgoing length + * @in_buf: Incoming payload (from EC) + * @in_len: Incoming length + */ +struct cros_ec_msg { + u8 version; + u8 cmd; + uint8_t *out_buf; + int out_len; + uint8_t *in_buf; + int in_len; +}; + +/** + * struct cros_ec_device - Information about a ChromeOS EC device + * + * @name: Name of this EC interface + * @priv: Private data + * @irq: Interrupt to use + * @din: input buffer (from EC) + * @dout: output buffer (to EC) + * \note + * These two buffers will always be dword-aligned and include enough + * space for up to 7 word-alignment bytes also, so we can ensure that + * the body of the message is always dword-aligned (64-bit). + * + * We use this alignment to keep ARM and x86 happy. Probably word + * alignment would be OK, there might be a small performance advantage + * to using dword. + * @din_size: size of din buffer + * @dout_size: size of dout buffer + * @command_send: send a command + * @command_recv: receive a command + * @ec_name: name of EC device (e.g. 'chromeos-ec') + * @phys_name: name of physical comms layer (e.g. 'i2c-4') + * @parent: pointer to parent device (e.g. i2c or spi device) + * @dev: Device pointer + * dev_lock: Lock to prevent concurrent access + * @wake_enabled: true if this device can wake the system from sleep + * @was_wake_device: true if this device was set to wake the system from + * sleep at the last suspend + * @event_notifier: interrupt event notifier for transport devices + */ +struct cros_ec_device { + const char *name; + void *priv; + int irq; + uint8_t *din; + uint8_t *dout; + int din_size; + int dout_size; + int (*command_send)(struct cros_ec_device *ec, + uint16_t cmd, void *out_buf, int out_len); + int (*command_recv)(struct cros_ec_device *ec, + uint16_t cmd, void *in_buf, int in_len); + int (*command_sendrecv)(struct cros_ec_device *ec, + uint16_t cmd, void *out_buf, int out_len, + void *in_buf, int in_len); + int (*command_xfer)(struct cros_ec_device *ec, + struct cros_ec_msg *msg); + + const char *ec_name; + const char *phys_name; + struct device *parent; + + /* These are --private-- fields - do not assign */ + struct device *dev; + struct mutex dev_lock; + bool wake_enabled; + bool was_wake_device; + struct blocking_notifier_head event_notifier; +}; + +/** + * cros_ec_suspend - Handle a suspend operation for the ChromeOS EC device + * + * This can be called by drivers to handle a suspend event. + * + * ec_dev: Device to suspend + * @return 0 if ok, -ve on error + */ +int cros_ec_suspend(struct cros_ec_device *ec_dev); + +/** + * cros_ec_resume - Handle a resume operation for the ChromeOS EC device + * + * This can be called by drivers to handle a resume event. + * + * @ec_dev: Device to resume + * @return 0 if ok, -ve on error + */ +int cros_ec_resume(struct cros_ec_device *ec_dev); + +/** + * cros_ec_prepare_tx - Prepare an outgoing message in the output buffer + * + * This is intended to be used by all ChromeOS EC drivers, but at present + * only SPI uses it. Once LPC uses the same protocol it can start using it. + * I2C could use it now, with a refactor of the existing code. + * + * @ec_dev: Device to register + * @msg: Message to write + */ +int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, + struct cros_ec_msg *msg); + +/** + * cros_ec_remove - Remove a ChromeOS EC + * + * Call this to deregister a ChromeOS EC. After this you should call + * cros_ec_free(). + * + * @ec_dev: Device to register + * @return 0 if ok, -ve on error + */ +int cros_ec_remove(struct cros_ec_device *ec_dev); + +/** + * cros_ec_register - Register a new ChromeOS EC, using the provided info + * + * Before calling this, allocate a pointer to a new device and then fill + * in all the fields up to the --private-- marker. + * + * @ec_dev: Device to register + * @return 0 if ok, -ve on error + */ +int cros_ec_register(struct cros_ec_device *ec_dev); + +#endif /* __LINUX_MFD_CROS_EC_H */ diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h new file mode 100644 index 000000000000..86fd06953bcd --- /dev/null +++ b/include/linux/mfd/cros_ec_commands.h @@ -0,0 +1,1369 @@ +/* + * Host communication command constants for ChromeOS EC + * + * Copyright (C) 2012 Google, Inc + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * The ChromeOS EC multi function device is used to mux all the requests + * to the EC device for its multiple features: keyboard controller, + * battery charging and regulator control, firmware update. + * + * NOTE: This file is copied verbatim from the ChromeOS EC Open Source + * project in an attempt to make future updates easy to make. + */ + +#ifndef __CROS_EC_COMMANDS_H +#define __CROS_EC_COMMANDS_H + +/* + * Protocol overview + * + * request: CMD [ P0 P1 P2 ... Pn S ] + * response: ERR [ P0 P1 P2 ... Pn S ] + * + * where the bytes are defined as follow : + * - CMD is the command code. (defined by EC_CMD_ constants) + * - ERR is the error code. (defined by EC_RES_ constants) + * - Px is the optional payload. + * it is not sent if the error code is not success. + * (defined by ec_params_ and ec_response_ structures) + * - S is the checksum which is the sum of all payload bytes. + * + * On LPC, CMD and ERR are sent/received at EC_LPC_ADDR_KERNEL|USER_CMD + * and the payloads are sent/received at EC_LPC_ADDR_KERNEL|USER_PARAM. + * On I2C, all bytes are sent serially in the same message. + */ + +/* Current version of this protocol */ +#define EC_PROTO_VERSION 0x00000002 + +/* Command version mask */ +#define EC_VER_MASK(version) (1UL << (version)) + +/* I/O addresses for ACPI commands */ +#define EC_LPC_ADDR_ACPI_DATA 0x62 +#define EC_LPC_ADDR_ACPI_CMD 0x66 + +/* I/O addresses for host command */ +#define EC_LPC_ADDR_HOST_DATA 0x200 +#define EC_LPC_ADDR_HOST_CMD 0x204 + +/* I/O addresses for host command args and params */ +#define EC_LPC_ADDR_HOST_ARGS 0x800 +#define EC_LPC_ADDR_HOST_PARAM 0x804 +#define EC_HOST_PARAM_SIZE 0x0fc /* Size of param area in bytes */ + +/* I/O addresses for host command params, old interface */ +#define EC_LPC_ADDR_OLD_PARAM 0x880 +#define EC_OLD_PARAM_SIZE 0x080 /* Size of param area in bytes */ + +/* EC command register bit functions */ +#define EC_LPC_CMDR_DATA (1 << 0) /* Data ready for host to read */ +#define EC_LPC_CMDR_PENDING (1 << 1) /* Write pending to EC */ +#define EC_LPC_CMDR_BUSY (1 << 2) /* EC is busy processing a command */ +#define EC_LPC_CMDR_CMD (1 << 3) /* Last host write was a command */ +#define EC_LPC_CMDR_ACPI_BRST (1 << 4) /* Burst mode (not used) */ +#define EC_LPC_CMDR_SCI (1 << 5) /* SCI event is pending */ +#define EC_LPC_CMDR_SMI (1 << 6) /* SMI event is pending */ + +#define EC_LPC_ADDR_MEMMAP 0x900 +#define EC_MEMMAP_SIZE 255 /* ACPI IO buffer max is 255 bytes */ +#define EC_MEMMAP_TEXT_MAX 8 /* Size of a string in the memory map */ + +/* The offset address of each type of data in mapped memory. */ +#define EC_MEMMAP_TEMP_SENSOR 0x00 /* Temp sensors */ +#define EC_MEMMAP_FAN 0x10 /* Fan speeds */ +#define EC_MEMMAP_TEMP_SENSOR_B 0x18 /* Temp sensors (second set) */ +#define EC_MEMMAP_ID 0x20 /* 'E' 'C' */ +#define EC_MEMMAP_ID_VERSION 0x22 /* Version of data in 0x20 - 0x2f */ +#define EC_MEMMAP_THERMAL_VERSION 0x23 /* Version of data in 0x00 - 0x1f */ +#define EC_MEMMAP_BATTERY_VERSION 0x24 /* Version of data in 0x40 - 0x7f */ +#define EC_MEMMAP_SWITCHES_VERSION 0x25 /* Version of data in 0x30 - 0x33 */ +#define EC_MEMMAP_EVENTS_VERSION 0x26 /* Version of data in 0x34 - 0x3f */ +#define EC_MEMMAP_HOST_CMD_FLAGS 0x27 /* Host command interface flags */ +#define EC_MEMMAP_SWITCHES 0x30 +#define EC_MEMMAP_HOST_EVENTS 0x34 +#define EC_MEMMAP_BATT_VOLT 0x40 /* Battery Present Voltage */ +#define EC_MEMMAP_BATT_RATE 0x44 /* Battery Present Rate */ +#define EC_MEMMAP_BATT_CAP 0x48 /* Battery Remaining Capacity */ +#define EC_MEMMAP_BATT_FLAG 0x4c /* Battery State, defined below */ +#define EC_MEMMAP_BATT_DCAP 0x50 /* Battery Design Capacity */ +#define EC_MEMMAP_BATT_DVLT 0x54 /* Battery Design Voltage */ +#define EC_MEMMAP_BATT_LFCC 0x58 /* Battery Last Full Charge Capacity */ +#define EC_MEMMAP_BATT_CCNT 0x5c /* Battery Cycle Count */ +#define EC_MEMMAP_BATT_MFGR 0x60 /* Battery Manufacturer String */ +#define EC_MEMMAP_BATT_MODEL 0x68 /* Battery Model Number String */ +#define EC_MEMMAP_BATT_SERIAL 0x70 /* Battery Serial Number String */ +#define EC_MEMMAP_BATT_TYPE 0x78 /* Battery Type String */ + +/* Number of temp sensors at EC_MEMMAP_TEMP_SENSOR */ +#define EC_TEMP_SENSOR_ENTRIES 16 +/* + * Number of temp sensors at EC_MEMMAP_TEMP_SENSOR_B. + * + * Valid only if EC_MEMMAP_THERMAL_VERSION returns >= 2. + */ +#define EC_TEMP_SENSOR_B_ENTRIES 8 +#define EC_TEMP_SENSOR_NOT_PRESENT 0xff +#define EC_TEMP_SENSOR_ERROR 0xfe +#define EC_TEMP_SENSOR_NOT_POWERED 0xfd +#define EC_TEMP_SENSOR_NOT_CALIBRATED 0xfc +/* + * The offset of temperature value stored in mapped memory. This allows + * reporting a temperature range of 200K to 454K = -73C to 181C. + */ +#define EC_TEMP_SENSOR_OFFSET 200 + +#define EC_FAN_SPEED_ENTRIES 4 /* Number of fans at EC_MEMMAP_FAN */ +#define EC_FAN_SPEED_NOT_PRESENT 0xffff /* Entry not present */ +#define EC_FAN_SPEED_STALLED 0xfffe /* Fan stalled */ + +/* Battery bit flags at EC_MEMMAP_BATT_FLAG. */ +#define EC_BATT_FLAG_AC_PRESENT 0x01 +#define EC_BATT_FLAG_BATT_PRESENT 0x02 +#define EC_BATT_FLAG_DISCHARGING 0x04 +#define EC_BATT_FLAG_CHARGING 0x08 +#define EC_BATT_FLAG_LEVEL_CRITICAL 0x10 + +/* Switch flags at EC_MEMMAP_SWITCHES */ +#define EC_SWITCH_LID_OPEN 0x01 +#define EC_SWITCH_POWER_BUTTON_PRESSED 0x02 +#define EC_SWITCH_WRITE_PROTECT_DISABLED 0x04 +/* Recovery requested via keyboard */ +#define EC_SWITCH_KEYBOARD_RECOVERY 0x08 +/* Recovery requested via dedicated signal (from servo board) */ +#define EC_SWITCH_DEDICATED_RECOVERY 0x10 +/* Was fake developer mode switch; now unused. Remove in next refactor. */ +#define EC_SWITCH_IGNORE0 0x20 + +/* Host command interface flags */ +/* Host command interface supports LPC args (LPC interface only) */ +#define EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED 0x01 + +/* Wireless switch flags */ +#define EC_WIRELESS_SWITCH_WLAN 0x01 +#define EC_WIRELESS_SWITCH_BLUETOOTH 0x02 + +/* + * This header file is used in coreboot both in C and ACPI code. The ACPI code + * is pre-processed to handle constants but the ASL compiler is unable to + * handle actual C code so keep it separate. + */ +#ifndef __ACPI__ + +/* LPC command status byte masks */ +/* EC has written a byte in the data register and host hasn't read it yet */ +#define EC_LPC_STATUS_TO_HOST 0x01 +/* Host has written a command/data byte and the EC hasn't read it yet */ +#define EC_LPC_STATUS_FROM_HOST 0x02 +/* EC is processing a command */ +#define EC_LPC_STATUS_PROCESSING 0x04 +/* Last write to EC was a command, not data */ +#define EC_LPC_STATUS_LAST_CMD 0x08 +/* EC is in burst mode. Unsupported by Chrome EC, so this bit is never set */ +#define EC_LPC_STATUS_BURST_MODE 0x10 +/* SCI event is pending (requesting SCI query) */ +#define EC_LPC_STATUS_SCI_PENDING 0x20 +/* SMI event is pending (requesting SMI query) */ +#define EC_LPC_STATUS_SMI_PENDING 0x40 +/* (reserved) */ +#define EC_LPC_STATUS_RESERVED 0x80 + +/* + * EC is busy. This covers both the EC processing a command, and the host has + * written a new command but the EC hasn't picked it up yet. + */ +#define EC_LPC_STATUS_BUSY_MASK \ + (EC_LPC_STATUS_FROM_HOST | EC_LPC_STATUS_PROCESSING) + +/* Host command response codes */ +enum ec_status { + EC_RES_SUCCESS = 0, + EC_RES_INVALID_COMMAND = 1, + EC_RES_ERROR = 2, + EC_RES_INVALID_PARAM = 3, + EC_RES_ACCESS_DENIED = 4, + EC_RES_INVALID_RESPONSE = 5, + EC_RES_INVALID_VERSION = 6, + EC_RES_INVALID_CHECKSUM = 7, + EC_RES_IN_PROGRESS = 8, /* Accepted, command in progress */ + EC_RES_UNAVAILABLE = 9, /* No response available */ + EC_RES_TIMEOUT = 10, /* We got a timeout */ + EC_RES_OVERFLOW = 11, /* Table / data overflow */ +}; + +/* + * Host event codes. Note these are 1-based, not 0-based, because ACPI query + * EC command uses code 0 to mean "no event pending". We explicitly specify + * each value in the enum listing so they won't change if we delete/insert an + * item or rearrange the list (it needs to be stable across platforms, not + * just within a single compiled instance). + */ +enum host_event_code { + EC_HOST_EVENT_LID_CLOSED = 1, + EC_HOST_EVENT_LID_OPEN = 2, + EC_HOST_EVENT_POWER_BUTTON = 3, + EC_HOST_EVENT_AC_CONNECTED = 4, + EC_HOST_EVENT_AC_DISCONNECTED = 5, + EC_HOST_EVENT_BATTERY_LOW = 6, + EC_HOST_EVENT_BATTERY_CRITICAL = 7, + EC_HOST_EVENT_BATTERY = 8, + EC_HOST_EVENT_THERMAL_THRESHOLD = 9, + EC_HOST_EVENT_THERMAL_OVERLOAD = 10, + EC_HOST_EVENT_THERMAL = 11, + EC_HOST_EVENT_USB_CHARGER = 12, + EC_HOST_EVENT_KEY_PRESSED = 13, + /* + * EC has finished initializing the host interface. The host can check + * for this event following sending a EC_CMD_REBOOT_EC command to + * determine when the EC is ready to accept subsequent commands. + */ + EC_HOST_EVENT_INTERFACE_READY = 14, + /* Keyboard recovery combo has been pressed */ + EC_HOST_EVENT_KEYBOARD_RECOVERY = 15, + + /* Shutdown due to thermal overload */ + EC_HOST_EVENT_THERMAL_SHUTDOWN = 16, + /* Shutdown due to battery level too low */ + EC_HOST_EVENT_BATTERY_SHUTDOWN = 17, + + /* + * 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 + * considered invalid by the host. This can happen when reading the + * raw event status via EC_MEMMAP_HOST_EVENTS but the LPC interface is + * not initialized on the EC, or improperly configured on the host. + */ + EC_HOST_EVENT_INVALID = 32 +}; +/* Host event mask */ +#define EC_HOST_EVENT_MASK(event_code) (1UL << ((event_code) - 1)) + +/* Arguments at EC_LPC_ADDR_HOST_ARGS */ +struct ec_lpc_host_args { + uint8_t flags; + uint8_t command_version; + uint8_t data_size; + /* + * Checksum; sum of command + flags + command_version + data_size + + * all params/response data bytes. + */ + uint8_t checksum; +} __packed; + +/* Flags for ec_lpc_host_args.flags */ +/* + * Args are from host. Data area at EC_LPC_ADDR_HOST_PARAM contains command + * params. + * + * If EC gets a command and this flag is not set, this is an old-style command. + * Command version is 0 and params from host are at EC_LPC_ADDR_OLD_PARAM with + * unknown length. EC must respond with an old-style response (that is, + * withouth setting EC_HOST_ARGS_FLAG_TO_HOST). + */ +#define EC_HOST_ARGS_FLAG_FROM_HOST 0x01 +/* + * Args are from EC. Data area at EC_LPC_ADDR_HOST_PARAM contains response. + * + * If EC responds to a command and this flag is not set, this is an old-style + * response. Command version is 0 and response data from EC is at + * EC_LPC_ADDR_OLD_PARAM with unknown length. + */ +#define EC_HOST_ARGS_FLAG_TO_HOST 0x02 + +/* + * Notes on commands: + * + * Each command is an 8-byte command value. Commands which take params or + * return response data specify structs for that data. If no struct is + * specified, the command does not input or output data, respectively. + * Parameter/response length is implicit in the structs. Some underlying + * communication protocols (I2C, SPI) may add length or checksum headers, but + * those are implementation-dependent and not defined here. + */ + +/*****************************************************************************/ +/* General / test commands */ + +/* + * Get protocol version, used to deal with non-backward compatible protocol + * changes. + */ +#define EC_CMD_PROTO_VERSION 0x00 + +struct ec_response_proto_version { + uint32_t version; +} __packed; + +/* + * Hello. This is a simple command to test the EC is responsive to + * commands. + */ +#define EC_CMD_HELLO 0x01 + +struct ec_params_hello { + uint32_t in_data; /* Pass anything here */ +} __packed; + +struct ec_response_hello { + uint32_t out_data; /* Output will be in_data + 0x01020304 */ +} __packed; + +/* Get version number */ +#define EC_CMD_GET_VERSION 0x02 + +enum ec_current_image { + EC_IMAGE_UNKNOWN = 0, + EC_IMAGE_RO, + EC_IMAGE_RW +}; + +struct ec_response_get_version { + /* Null-terminated version strings for RO, RW */ + char version_string_ro[32]; + char version_string_rw[32]; + char reserved[32]; /* Was previously RW-B string */ + uint32_t current_image; /* One of ec_current_image */ +} __packed; + +/* Read test */ +#define EC_CMD_READ_TEST 0x03 + +struct ec_params_read_test { + uint32_t offset; /* Starting value for read buffer */ + uint32_t size; /* Size to read in bytes */ +} __packed; + +struct ec_response_read_test { + uint32_t data[32]; +} __packed; + +/* + * Get build information + * + * Response is null-terminated string. + */ +#define EC_CMD_GET_BUILD_INFO 0x04 + +/* Get chip info */ +#define EC_CMD_GET_CHIP_INFO 0x05 + +struct ec_response_get_chip_info { + /* Null-terminated strings */ + char vendor[32]; + char name[32]; + char revision[32]; /* Mask version */ +} __packed; + +/* Get board HW version */ +#define EC_CMD_GET_BOARD_VERSION 0x06 + +struct ec_response_board_version { + uint16_t board_version; /* A monotonously incrementing number. */ +} __packed; + +/* + * Read memory-mapped data. + * + * This is an alternate interface to memory-mapped data for bus protocols + * which don't support direct-mapped memory - I2C, SPI, etc. + * + * Response is params.size bytes of data. + */ +#define EC_CMD_READ_MEMMAP 0x07 + +struct ec_params_read_memmap { + uint8_t offset; /* Offset in memmap (EC_MEMMAP_*) */ + uint8_t size; /* Size to read in bytes */ +} __packed; + +/* Read versions supported for a command */ +#define EC_CMD_GET_CMD_VERSIONS 0x08 + +struct ec_params_get_cmd_versions { + uint8_t cmd; /* Command to check */ +} __packed; + +struct ec_response_get_cmd_versions { + /* + * Mask of supported versions; use EC_VER_MASK() to compare with a + * desired version. + */ + uint32_t version_mask; +} __packed; + +/* + * Check EC communcations status (busy). This is needed on i2c/spi but not + * on lpc since it has its own out-of-band busy indicator. + * + * lpc must read the status from the command register. Attempting this on + * lpc will overwrite the args/parameter space and corrupt its data. + */ +#define EC_CMD_GET_COMMS_STATUS 0x09 + +/* Avoid using ec_status which is for return values */ +enum ec_comms_status { + EC_COMMS_STATUS_PROCESSING = 1 << 0, /* Processing cmd */ +}; + +struct ec_response_get_comms_status { + uint32_t flags; /* Mask of enum ec_comms_status */ +} __packed; + + +/*****************************************************************************/ +/* Flash commands */ + +/* Get flash info */ +#define EC_CMD_FLASH_INFO 0x10 + +struct ec_response_flash_info { + /* Usable flash size, in bytes */ + uint32_t flash_size; + /* + * Write block size. Write offset and size must be a multiple + * of this. + */ + uint32_t write_block_size; + /* + * Erase block size. Erase offset and size must be a multiple + * of this. + */ + uint32_t erase_block_size; + /* + * Protection block size. Protection offset and size must be a + * multiple of this. + */ + uint32_t protect_block_size; +} __packed; + +/* + * Read flash + * + * Response is params.size bytes of data. + */ +#define EC_CMD_FLASH_READ 0x11 + +struct ec_params_flash_read { + uint32_t offset; /* Byte offset to read */ + uint32_t size; /* Size to read in bytes */ +} __packed; + +/* Write flash */ +#define EC_CMD_FLASH_WRITE 0x12 + +struct ec_params_flash_write { + uint32_t offset; /* Byte offset to write */ + uint32_t size; /* Size to write in bytes */ + /* + * Data to write. Could really use EC_PARAM_SIZE - 8, but tidiest to + * use a power of 2 so writes stay aligned. + */ + uint8_t data[64]; +} __packed; + +/* Erase flash */ +#define EC_CMD_FLASH_ERASE 0x13 + +struct ec_params_flash_erase { + uint32_t offset; /* Byte offset to erase */ + uint32_t size; /* Size to erase in bytes */ +} __packed; + +/* + * Get/set flash protection. + * + * If mask!=0, sets/clear the requested bits of flags. Depending on the + * firmware write protect GPIO, not all flags will take effect immediately; + * some flags require a subsequent hard reset to take effect. Check the + * returned flags bits to see what actually happened. + * + * If mask=0, simply returns the current flags state. + */ +#define EC_CMD_FLASH_PROTECT 0x15 +#define EC_VER_FLASH_PROTECT 1 /* Command version 1 */ + +/* Flags for flash protection */ +/* RO flash code protected when the EC boots */ +#define EC_FLASH_PROTECT_RO_AT_BOOT (1 << 0) +/* + * RO flash code protected now. If this bit is set, at-boot status cannot + * be changed. + */ +#define EC_FLASH_PROTECT_RO_NOW (1 << 1) +/* Entire flash code protected now, until reboot. */ +#define EC_FLASH_PROTECT_ALL_NOW (1 << 2) +/* Flash write protect GPIO is asserted now */ +#define EC_FLASH_PROTECT_GPIO_ASSERTED (1 << 3) +/* Error - at least one bank of flash is stuck locked, and cannot be unlocked */ +#define EC_FLASH_PROTECT_ERROR_STUCK (1 << 4) +/* + * Error - flash protection is in inconsistent state. At least one bank of + * flash which should be protected is not protected. Usually fixed by + * re-requesting the desired flags, or by a hard reset if that fails. + */ +#define EC_FLASH_PROTECT_ERROR_INCONSISTENT (1 << 5) +/* Entile flash code protected when the EC boots */ +#define EC_FLASH_PROTECT_ALL_AT_BOOT (1 << 6) + +struct ec_params_flash_protect { + uint32_t mask; /* Bits in flags to apply */ + uint32_t flags; /* New flags to apply */ +} __packed; + +struct ec_response_flash_protect { + /* Current value of flash protect flags */ + uint32_t flags; + /* + * Flags which are valid on this platform. This allows the caller + * to distinguish between flags which aren't set vs. flags which can't + * be set on this platform. + */ + uint32_t valid_flags; + /* Flags which can be changed given the current protection state */ + uint32_t writable_flags; +} __packed; + +/* + * Note: commands 0x14 - 0x19 version 0 were old commands to get/set flash + * write protect. These commands may be reused with version > 0. + */ + +/* Get the region offset/size */ +#define EC_CMD_FLASH_REGION_INFO 0x16 +#define EC_VER_FLASH_REGION_INFO 1 + +enum ec_flash_region { + /* Region which holds read-only EC image */ + EC_FLASH_REGION_RO, + /* Region which holds rewritable EC image */ + EC_FLASH_REGION_RW, + /* + * Region which should be write-protected in the factory (a superset of + * EC_FLASH_REGION_RO) + */ + EC_FLASH_REGION_WP_RO, +}; + +struct ec_params_flash_region_info { + uint32_t region; /* enum ec_flash_region */ +} __packed; + +struct ec_response_flash_region_info { + uint32_t offset; + uint32_t size; +} __packed; + +/* Read/write VbNvContext */ +#define EC_CMD_VBNV_CONTEXT 0x17 +#define EC_VER_VBNV_CONTEXT 1 +#define EC_VBNV_BLOCK_SIZE 16 + +enum ec_vbnvcontext_op { + EC_VBNV_CONTEXT_OP_READ, + EC_VBNV_CONTEXT_OP_WRITE, +}; + +struct ec_params_vbnvcontext { + uint32_t op; + uint8_t block[EC_VBNV_BLOCK_SIZE]; +} __packed; + +struct ec_response_vbnvcontext { + uint8_t block[EC_VBNV_BLOCK_SIZE]; +} __packed; + +/*****************************************************************************/ +/* PWM commands */ + +/* Get fan target RPM */ +#define EC_CMD_PWM_GET_FAN_TARGET_RPM 0x20 + +struct ec_response_pwm_get_fan_rpm { + uint32_t rpm; +} __packed; + +/* Set target fan RPM */ +#define EC_CMD_PWM_SET_FAN_TARGET_RPM 0x21 + +struct ec_params_pwm_set_fan_target_rpm { + uint32_t rpm; +} __packed; + +/* Get keyboard backlight */ +#define EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT 0x22 + +struct ec_response_pwm_get_keyboard_backlight { + uint8_t percent; + uint8_t enabled; +} __packed; + +/* Set keyboard backlight */ +#define EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT 0x23 + +struct ec_params_pwm_set_keyboard_backlight { + uint8_t percent; +} __packed; + +/* Set target fan PWM duty cycle */ +#define EC_CMD_PWM_SET_FAN_DUTY 0x24 + +struct ec_params_pwm_set_fan_duty { + uint32_t percent; +} __packed; + +/*****************************************************************************/ +/* + * Lightbar commands. This looks worse than it is. Since we only use one HOST + * command to say "talk to the lightbar", we put the "and tell it to do X" part + * into a subcommand. We'll make separate structs for subcommands with + * different input args, so that we know how much to expect. + */ +#define EC_CMD_LIGHTBAR_CMD 0x28 + +struct rgb_s { + uint8_t r, g, b; +}; + +#define LB_BATTERY_LEVELS 4 +/* List of tweakable parameters. NOTE: It's __packed so it can be sent in a + * host command, but the alignment is the same regardless. Keep it that way. + */ +struct lightbar_params { + /* Timing */ + int google_ramp_up; + int google_ramp_down; + int s3s0_ramp_up; + int s0_tick_delay[2]; /* AC=0/1 */ + int s0a_tick_delay[2]; /* AC=0/1 */ + int s0s3_ramp_down; + int s3_sleep_for; + int s3_ramp_up; + int s3_ramp_down; + + /* Oscillation */ + uint8_t new_s0; + uint8_t osc_min[2]; /* AC=0/1 */ + uint8_t osc_max[2]; /* AC=0/1 */ + uint8_t w_ofs[2]; /* AC=0/1 */ + + /* Brightness limits based on the backlight and AC. */ + uint8_t bright_bl_off_fixed[2]; /* AC=0/1 */ + uint8_t bright_bl_on_min[2]; /* AC=0/1 */ + uint8_t bright_bl_on_max[2]; /* AC=0/1 */ + + /* Battery level thresholds */ + uint8_t battery_threshold[LB_BATTERY_LEVELS - 1]; + + /* Map [AC][battery_level] to color index */ + uint8_t s0_idx[2][LB_BATTERY_LEVELS]; /* AP is running */ + uint8_t s3_idx[2][LB_BATTERY_LEVELS]; /* AP is sleeping */ + + /* Color palette */ + struct rgb_s color[8]; /* 0-3 are Google colors */ +} __packed; + +struct ec_params_lightbar { + uint8_t cmd; /* Command (see enum lightbar_command) */ + union { + struct { + /* no args */ + } dump, off, on, init, get_seq, get_params; + + struct num { + uint8_t num; + } brightness, seq, demo; + + struct reg { + uint8_t ctrl, reg, value; + } reg; + + struct rgb { + uint8_t led, red, green, blue; + } rgb; + + struct lightbar_params set_params; + }; +} __packed; + +struct ec_response_lightbar { + union { + struct dump { + struct { + uint8_t reg; + uint8_t ic0; + uint8_t ic1; + } vals[23]; + } dump; + + struct get_seq { + uint8_t num; + } get_seq; + + struct lightbar_params get_params; + + struct { + /* no return params */ + } off, on, init, brightness, seq, reg, rgb, demo, set_params; + }; +} __packed; + +/* Lightbar commands */ +enum lightbar_command { + LIGHTBAR_CMD_DUMP = 0, + LIGHTBAR_CMD_OFF = 1, + LIGHTBAR_CMD_ON = 2, + LIGHTBAR_CMD_INIT = 3, + LIGHTBAR_CMD_BRIGHTNESS = 4, + LIGHTBAR_CMD_SEQ = 5, + LIGHTBAR_CMD_REG = 6, + LIGHTBAR_CMD_RGB = 7, + LIGHTBAR_CMD_GET_SEQ = 8, + LIGHTBAR_CMD_DEMO = 9, + LIGHTBAR_CMD_GET_PARAMS = 10, + LIGHTBAR_CMD_SET_PARAMS = 11, + LIGHTBAR_NUM_CMDS +}; + +/*****************************************************************************/ +/* Verified boot commands */ + +/* + * Note: command code 0x29 version 0 was VBOOT_CMD in Link EVT; it may be + * reused for other purposes with version > 0. + */ + +/* Verified boot hash command */ +#define EC_CMD_VBOOT_HASH 0x2A + +struct ec_params_vboot_hash { + uint8_t cmd; /* enum ec_vboot_hash_cmd */ + uint8_t hash_type; /* enum ec_vboot_hash_type */ + uint8_t nonce_size; /* Nonce size; may be 0 */ + uint8_t reserved0; /* Reserved; set 0 */ + uint32_t offset; /* Offset in flash to hash */ + uint32_t size; /* Number of bytes to hash */ + uint8_t nonce_data[64]; /* Nonce data; ignored if nonce_size=0 */ +} __packed; + +struct ec_response_vboot_hash { + uint8_t status; /* enum ec_vboot_hash_status */ + uint8_t hash_type; /* enum ec_vboot_hash_type */ + uint8_t digest_size; /* Size of hash digest in bytes */ + uint8_t reserved0; /* Ignore; will be 0 */ + uint32_t offset; /* Offset in flash which was hashed */ + uint32_t size; /* Number of bytes hashed */ + uint8_t hash_digest[64]; /* Hash digest data */ +} __packed; + +enum ec_vboot_hash_cmd { + EC_VBOOT_HASH_GET = 0, /* Get current hash status */ + EC_VBOOT_HASH_ABORT = 1, /* Abort calculating current hash */ + EC_VBOOT_HASH_START = 2, /* Start computing a new hash */ + EC_VBOOT_HASH_RECALC = 3, /* Synchronously compute a new hash */ +}; + +enum ec_vboot_hash_type { + EC_VBOOT_HASH_TYPE_SHA256 = 0, /* SHA-256 */ +}; + +enum ec_vboot_hash_status { + EC_VBOOT_HASH_STATUS_NONE = 0, /* No hash (not started, or aborted) */ + EC_VBOOT_HASH_STATUS_DONE = 1, /* Finished computing a hash */ + EC_VBOOT_HASH_STATUS_BUSY = 2, /* Busy computing a hash */ +}; + +/* + * Special values for offset for EC_VBOOT_HASH_START and EC_VBOOT_HASH_RECALC. + * If one of these is specified, the EC will automatically update offset and + * size to the correct values for the specified image (RO or RW). + */ +#define EC_VBOOT_HASH_OFFSET_RO 0xfffffffe +#define EC_VBOOT_HASH_OFFSET_RW 0xfffffffd + +/*****************************************************************************/ +/* USB charging control commands */ + +/* Set USB port charging mode */ +#define EC_CMD_USB_CHARGE_SET_MODE 0x30 + +struct ec_params_usb_charge_set_mode { + uint8_t usb_port_id; + uint8_t mode; +} __packed; + +/*****************************************************************************/ +/* Persistent storage for host */ + +/* Maximum bytes that can be read/written in a single command */ +#define EC_PSTORE_SIZE_MAX 64 + +/* Get persistent storage info */ +#define EC_CMD_PSTORE_INFO 0x40 + +struct ec_response_pstore_info { + /* Persistent storage size, in bytes */ + uint32_t pstore_size; + /* Access size; read/write offset and size must be a multiple of this */ + uint32_t access_size; +} __packed; + +/* + * Read persistent storage + * + * Response is params.size bytes of data. + */ +#define EC_CMD_PSTORE_READ 0x41 + +struct ec_params_pstore_read { + uint32_t offset; /* Byte offset to read */ + uint32_t size; /* Size to read in bytes */ +} __packed; + +/* Write persistent storage */ +#define EC_CMD_PSTORE_WRITE 0x42 + +struct ec_params_pstore_write { + uint32_t offset; /* Byte offset to write */ + uint32_t size; /* Size to write in bytes */ + uint8_t data[EC_PSTORE_SIZE_MAX]; +} __packed; + +/*****************************************************************************/ +/* Real-time clock */ + +/* RTC params and response structures */ +struct ec_params_rtc { + uint32_t time; +} __packed; + +struct ec_response_rtc { + uint32_t time; +} __packed; + +/* These use ec_response_rtc */ +#define EC_CMD_RTC_GET_VALUE 0x44 +#define EC_CMD_RTC_GET_ALARM 0x45 + +/* These all use ec_params_rtc */ +#define EC_CMD_RTC_SET_VALUE 0x46 +#define EC_CMD_RTC_SET_ALARM 0x47 + +/*****************************************************************************/ +/* Port80 log access */ + +/* Get last port80 code from previous boot */ +#define EC_CMD_PORT80_LAST_BOOT 0x48 + +struct ec_response_port80_last_boot { + uint16_t code; +} __packed; + +/*****************************************************************************/ +/* Thermal engine commands */ + +/* Set thershold value */ +#define EC_CMD_THERMAL_SET_THRESHOLD 0x50 + +struct ec_params_thermal_set_threshold { + uint8_t sensor_type; + uint8_t threshold_id; + uint16_t value; +} __packed; + +/* Get threshold value */ +#define EC_CMD_THERMAL_GET_THRESHOLD 0x51 + +struct ec_params_thermal_get_threshold { + uint8_t sensor_type; + uint8_t threshold_id; +} __packed; + +struct ec_response_thermal_get_threshold { + uint16_t value; +} __packed; + +/* Toggle automatic fan control */ +#define EC_CMD_THERMAL_AUTO_FAN_CTRL 0x52 + +/* Get TMP006 calibration data */ +#define EC_CMD_TMP006_GET_CALIBRATION 0x53 + +struct ec_params_tmp006_get_calibration { + uint8_t index; +} __packed; + +struct ec_response_tmp006_get_calibration { + float s0; + float b0; + float b1; + float b2; +} __packed; + +/* Set TMP006 calibration data */ +#define EC_CMD_TMP006_SET_CALIBRATION 0x54 + +struct ec_params_tmp006_set_calibration { + uint8_t index; + uint8_t reserved[3]; /* Reserved; set 0 */ + float s0; + float b0; + float b1; + float b2; +} __packed; + +/*****************************************************************************/ +/* MKBP - Matrix KeyBoard Protocol */ + +/* + * Read key state + * + * Returns raw data for keyboard cols; see ec_response_mkbp_info.cols for + * expected response size. + */ +#define EC_CMD_MKBP_STATE 0x60 + +/* Provide information about the matrix : number of rows and columns */ +#define EC_CMD_MKBP_INFO 0x61 + +struct ec_response_mkbp_info { + uint32_t rows; + uint32_t cols; + uint8_t switches; +} __packed; + +/* Simulate key press */ +#define EC_CMD_MKBP_SIMULATE_KEY 0x62 + +struct ec_params_mkbp_simulate_key { + uint8_t col; + uint8_t row; + uint8_t pressed; +} __packed; + +/* Configure keyboard scanning */ +#define EC_CMD_MKBP_SET_CONFIG 0x64 +#define EC_CMD_MKBP_GET_CONFIG 0x65 + +/* flags */ +enum mkbp_config_flags { + EC_MKBP_FLAGS_ENABLE = 1, /* Enable keyboard scanning */ +}; + +enum mkbp_config_valid { + EC_MKBP_VALID_SCAN_PERIOD = 1 << 0, + EC_MKBP_VALID_POLL_TIMEOUT = 1 << 1, + EC_MKBP_VALID_MIN_POST_SCAN_DELAY = 1 << 3, + EC_MKBP_VALID_OUTPUT_SETTLE = 1 << 4, + EC_MKBP_VALID_DEBOUNCE_DOWN = 1 << 5, + EC_MKBP_VALID_DEBOUNCE_UP = 1 << 6, + EC_MKBP_VALID_FIFO_MAX_DEPTH = 1 << 7, +}; + +/* Configuration for our key scanning algorithm */ +struct ec_mkbp_config { + uint32_t valid_mask; /* valid fields */ + uint8_t flags; /* some flags (enum mkbp_config_flags) */ + uint8_t valid_flags; /* which flags are valid */ + uint16_t scan_period_us; /* period between start of scans */ + /* revert to interrupt mode after no activity for this long */ + uint32_t poll_timeout_us; + /* + * minimum post-scan relax time. Once we finish a scan we check + * the time until we are due to start the next one. If this time is + * shorter this field, we use this instead. + */ + uint16_t min_post_scan_delay_us; + /* delay between setting up output and waiting for it to settle */ + uint16_t output_settle_us; + uint16_t debounce_down_us; /* time for debounce on key down */ + uint16_t debounce_up_us; /* time for debounce on key up */ + /* maximum depth to allow for fifo (0 = no keyscan output) */ + uint8_t fifo_max_depth; +} __packed; + +struct ec_params_mkbp_set_config { + struct ec_mkbp_config config; +} __packed; + +struct ec_response_mkbp_get_config { + struct ec_mkbp_config config; +} __packed; + +/* Run the key scan emulation */ +#define EC_CMD_KEYSCAN_SEQ_CTRL 0x66 + +enum ec_keyscan_seq_cmd { + EC_KEYSCAN_SEQ_STATUS = 0, /* Get status information */ + EC_KEYSCAN_SEQ_CLEAR = 1, /* Clear sequence */ + EC_KEYSCAN_SEQ_ADD = 2, /* Add item to sequence */ + EC_KEYSCAN_SEQ_START = 3, /* Start running sequence */ + EC_KEYSCAN_SEQ_COLLECT = 4, /* Collect sequence summary data */ +}; + +enum ec_collect_flags { + /* + * Indicates this scan was processed by the EC. Due to timing, some + * scans may be skipped. + */ + EC_KEYSCAN_SEQ_FLAG_DONE = 1 << 0, +}; + +struct ec_collect_item { + uint8_t flags; /* some flags (enum ec_collect_flags) */ +}; + +struct ec_params_keyscan_seq_ctrl { + uint8_t cmd; /* Command to send (enum ec_keyscan_seq_cmd) */ + union { + struct { + uint8_t active; /* still active */ + uint8_t num_items; /* number of items */ + /* Current item being presented */ + uint8_t cur_item; + } status; + struct { + /* + * Absolute time for this scan, measured from the + * start of the sequence. + */ + uint32_t time_us; + uint8_t scan[0]; /* keyscan data */ + } add; + struct { + uint8_t start_item; /* First item to return */ + uint8_t num_items; /* Number of items to return */ + } collect; + }; +} __packed; + +struct ec_result_keyscan_seq_ctrl { + union { + struct { + uint8_t num_items; /* Number of items */ + /* Data for each item */ + struct ec_collect_item item[0]; + } collect; + }; +} __packed; + +/*****************************************************************************/ +/* Temperature sensor commands */ + +/* Read temperature sensor info */ +#define EC_CMD_TEMP_SENSOR_GET_INFO 0x70 + +struct ec_params_temp_sensor_get_info { + uint8_t id; +} __packed; + +struct ec_response_temp_sensor_get_info { + char sensor_name[32]; + uint8_t sensor_type; +} __packed; + +/*****************************************************************************/ + +/* + * Note: host commands 0x80 - 0x87 are reserved to avoid conflict with ACPI + * commands accidentally sent to the wrong interface. See the ACPI section + * below. + */ + +/*****************************************************************************/ +/* Host event commands */ + +/* + * Host event mask params and response structures, shared by all of the host + * event commands below. + */ +struct ec_params_host_event_mask { + uint32_t mask; +} __packed; + +struct ec_response_host_event_mask { + uint32_t mask; +} __packed; + +/* These all use ec_response_host_event_mask */ +#define EC_CMD_HOST_EVENT_GET_B 0x87 +#define EC_CMD_HOST_EVENT_GET_SMI_MASK 0x88 +#define EC_CMD_HOST_EVENT_GET_SCI_MASK 0x89 +#define EC_CMD_HOST_EVENT_GET_WAKE_MASK 0x8d + +/* These all use ec_params_host_event_mask */ +#define EC_CMD_HOST_EVENT_SET_SMI_MASK 0x8a +#define EC_CMD_HOST_EVENT_SET_SCI_MASK 0x8b +#define EC_CMD_HOST_EVENT_CLEAR 0x8c +#define EC_CMD_HOST_EVENT_SET_WAKE_MASK 0x8e +#define EC_CMD_HOST_EVENT_CLEAR_B 0x8f + +/*****************************************************************************/ +/* Switch commands */ + +/* Enable/disable LCD backlight */ +#define EC_CMD_SWITCH_ENABLE_BKLIGHT 0x90 + +struct ec_params_switch_enable_backlight { + uint8_t enabled; +} __packed; + +/* Enable/disable WLAN/Bluetooth */ +#define EC_CMD_SWITCH_ENABLE_WIRELESS 0x91 + +struct ec_params_switch_enable_wireless { + uint8_t enabled; +} __packed; + +/*****************************************************************************/ +/* GPIO commands. Only available on EC if write protect has been disabled. */ + +/* Set GPIO output value */ +#define EC_CMD_GPIO_SET 0x92 + +struct ec_params_gpio_set { + char name[32]; + uint8_t val; +} __packed; + +/* Get GPIO value */ +#define EC_CMD_GPIO_GET 0x93 + +struct ec_params_gpio_get { + char name[32]; +} __packed; +struct ec_response_gpio_get { + uint8_t val; +} __packed; + +/*****************************************************************************/ +/* I2C commands. Only available when flash write protect is unlocked. */ + +/* Read I2C bus */ +#define EC_CMD_I2C_READ 0x94 + +struct ec_params_i2c_read { + uint16_t addr; + uint8_t read_size; /* Either 8 or 16. */ + uint8_t port; + uint8_t offset; +} __packed; +struct ec_response_i2c_read { + uint16_t data; +} __packed; + +/* Write I2C bus */ +#define EC_CMD_I2C_WRITE 0x95 + +struct ec_params_i2c_write { + uint16_t data; + uint16_t addr; + uint8_t write_size; /* Either 8 or 16. */ + uint8_t port; + uint8_t offset; +} __packed; + +/*****************************************************************************/ +/* Charge state commands. Only available when flash write protect unlocked. */ + +/* Force charge state machine to stop in idle mode */ +#define EC_CMD_CHARGE_FORCE_IDLE 0x96 + +struct ec_params_force_idle { + uint8_t enabled; +} __packed; + +/*****************************************************************************/ +/* Console commands. Only available when flash write protect is unlocked. */ + +/* Snapshot console output buffer for use by EC_CMD_CONSOLE_READ. */ +#define EC_CMD_CONSOLE_SNAPSHOT 0x97 + +/* + * Read next chunk of data from saved snapshot. + * + * Response is null-terminated string. Empty string, if there is no more + * remaining output. + */ +#define EC_CMD_CONSOLE_READ 0x98 + +/*****************************************************************************/ + +/* + * Cut off battery power output if the battery supports. + * + * For unsupported battery, just don't implement this command and lets EC + * return EC_RES_INVALID_COMMAND. + */ +#define EC_CMD_BATTERY_CUT_OFF 0x99 + +/*****************************************************************************/ +/* Temporary debug commands. TODO: remove this crosbug.com/p/13849 */ + +/* + * Dump charge state machine context. + * + * Response is a binary dump of charge state machine context. + */ +#define EC_CMD_CHARGE_DUMP 0xa0 + +/* + * Set maximum battery charging current. + */ +#define EC_CMD_CHARGE_CURRENT_LIMIT 0xa1 + +struct ec_params_current_limit { + uint32_t limit; +} __packed; + +/*****************************************************************************/ +/* System commands */ + +/* + * TODO: this is a confusing name, since it doesn't necessarily reboot the EC. + * Rename to "set image" or something similar. + */ +#define EC_CMD_REBOOT_EC 0xd2 + +/* Command */ +enum ec_reboot_cmd { + EC_REBOOT_CANCEL = 0, /* Cancel a pending reboot */ + EC_REBOOT_JUMP_RO = 1, /* Jump to RO without rebooting */ + EC_REBOOT_JUMP_RW = 2, /* Jump to RW without rebooting */ + /* (command 3 was jump to RW-B) */ + EC_REBOOT_COLD = 4, /* Cold-reboot */ + EC_REBOOT_DISABLE_JUMP = 5, /* Disable jump until next reboot */ + EC_REBOOT_HIBERNATE = 6 /* Hibernate EC */ +}; + +/* Flags for ec_params_reboot_ec.reboot_flags */ +#define EC_REBOOT_FLAG_RESERVED0 (1 << 0) /* Was recovery request */ +#define EC_REBOOT_FLAG_ON_AP_SHUTDOWN (1 << 1) /* Reboot after AP shutdown */ + +struct ec_params_reboot_ec { + uint8_t cmd; /* enum ec_reboot_cmd */ + uint8_t flags; /* See EC_REBOOT_FLAG_* */ +} __packed; + +/* + * Get information on last EC panic. + * + * Returns variable-length platform-dependent panic information. See panic.h + * for details. + */ +#define EC_CMD_GET_PANIC_INFO 0xd3 + +/*****************************************************************************/ +/* + * ACPI commands + * + * These are valid ONLY on the ACPI command/data port. + */ + +/* + * ACPI Read Embedded Controller + * + * This reads from ACPI memory space on the EC (EC_ACPI_MEM_*). + * + * Use the following sequence: + * + * - Write EC_CMD_ACPI_READ to EC_LPC_ADDR_ACPI_CMD + * - Wait for EC_LPC_CMDR_PENDING bit to clear + * - Write address to EC_LPC_ADDR_ACPI_DATA + * - Wait for EC_LPC_CMDR_DATA bit to set + * - Read value from EC_LPC_ADDR_ACPI_DATA + */ +#define EC_CMD_ACPI_READ 0x80 + +/* + * ACPI Write Embedded Controller + * + * This reads from ACPI memory space on the EC (EC_ACPI_MEM_*). + * + * Use the following sequence: + * + * - Write EC_CMD_ACPI_WRITE to EC_LPC_ADDR_ACPI_CMD + * - Wait for EC_LPC_CMDR_PENDING bit to clear + * - Write address to EC_LPC_ADDR_ACPI_DATA + * - Wait for EC_LPC_CMDR_PENDING bit to clear + * - Write value to EC_LPC_ADDR_ACPI_DATA + */ +#define EC_CMD_ACPI_WRITE 0x81 + +/* + * ACPI Query Embedded Controller + * + * This clears the lowest-order bit in the currently pending host events, and + * sets the result code to the 1-based index of the bit (event 0x00000001 = 1, + * event 0x80000000 = 32), or 0 if no event was pending. + */ +#define EC_CMD_ACPI_QUERY_EVENT 0x84 + +/* Valid addresses in ACPI memory space, for read/write commands */ +/* Memory space version; set to EC_ACPI_MEM_VERSION_CURRENT */ +#define EC_ACPI_MEM_VERSION 0x00 +/* + * Test location; writing value here updates test compliment byte to (0xff - + * value). + */ +#define EC_ACPI_MEM_TEST 0x01 +/* Test compliment; writes here are ignored. */ +#define EC_ACPI_MEM_TEST_COMPLIMENT 0x02 +/* Keyboard backlight brightness percent (0 - 100) */ +#define EC_ACPI_MEM_KEYBOARD_BACKLIGHT 0x03 + +/* Current version of ACPI memory address space */ +#define EC_ACPI_MEM_VERSION_CURRENT 1 + + +/*****************************************************************************/ +/* + * Special commands + * + * These do not follow the normal rules for commands. See each command for + * details. + */ + +/* + * Reboot NOW + * + * This command will work even when the EC LPC interface is busy, because the + * reboot command is processed at interrupt level. Note that when the EC + * reboots, the host will reboot too, so there is no response to this command. + * + * Use EC_CMD_REBOOT_EC to reboot the EC more politely. + */ +#define EC_CMD_REBOOT 0xd1 /* Think "die" */ + +/* + * Resend last response (not supported on LPC). + * + * Returns EC_RES_UNAVAILABLE if there is no response available - for example, + * there was no previous command, or the previous command's response was too + * big to save. + */ +#define EC_CMD_RESEND_RESPONSE 0xdb + +/* + * This header byte on a command indicate version 0. Any header byte less + * than this means that we are talking to an old EC which doesn't support + * versioning. In that case, we assume version 0. + * + * Header bytes greater than this indicate a later version. For example, + * EC_CMD_VERSION0 + 1 means we are using version 1. + * + * The old EC interface must not use commands 0dc or higher. + */ +#define EC_CMD_VERSION0 0xdc + +#endif /* !__ACPI__ */ + +#endif /* __CROS_EC_COMMANDS_H */ diff --git a/include/linux/mfd/da9052/da9052.h b/include/linux/mfd/da9052/da9052.h index 786d02eb79d2..21e21b81cc75 100644 --- a/include/linux/mfd/da9052/da9052.h +++ b/include/linux/mfd/da9052/da9052.h @@ -148,10 +148,15 @@ static inline int da9052_group_read(struct da9052 *da9052, unsigned char reg, unsigned reg_cnt, unsigned char *val) { int ret; + unsigned int tmp; + int i; - ret = regmap_bulk_read(da9052->regmap, reg, val, reg_cnt); - if (ret < 0) - return ret; + for (i = 0; i < reg_cnt; i++) { + ret = regmap_read(da9052->regmap, reg + i, &tmp); + val[i] = (unsigned char)tmp; + if (ret < 0) + return ret; + } if (da9052->fix_io) { ret = da9052->fix_io(da9052, reg); @@ -166,10 +171,13 @@ static inline int da9052_group_write(struct da9052 *da9052, unsigned char reg, unsigned reg_cnt, unsigned char *val) { int ret; + int i; - ret = regmap_raw_write(da9052->regmap, reg, val, reg_cnt); - if (ret < 0) - return ret; + for (i = 0; i < reg_cnt; i++) { + ret = regmap_write(da9052->regmap, reg + i, val[i]); + if (ret < 0) + return ret; + } if (da9052->fix_io) { ret = da9052->fix_io(da9052, reg); diff --git a/include/linux/mfd/da9063/core.h b/include/linux/mfd/da9063/core.h new file mode 100644 index 000000000000..2d2a0af675fd --- /dev/null +++ b/include/linux/mfd/da9063/core.h @@ -0,0 +1,93 @@ +/* + * Definitions for DA9063 MFD driver + * + * Copyright 2012 Dialog Semiconductor Ltd. + * + * Author: Michal Hajduk <michal.hajduk@diasemi.com> + * Krystian Garbaciak <krystian.garbaciak@diasemi.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 __MFD_DA9063_CORE_H__ +#define __MFD_DA9063_CORE_H__ + +#include <linux/interrupt.h> +#include <linux/mfd/da9063/registers.h> + +/* DA9063 modules */ +#define DA9063_DRVNAME_CORE "da9063-core" +#define DA9063_DRVNAME_REGULATORS "da9063-regulators" +#define DA9063_DRVNAME_LEDS "da9063-leds" +#define DA9063_DRVNAME_WATCHDOG "da9063-watchdog" +#define DA9063_DRVNAME_HWMON "da9063-hwmon" +#define DA9063_DRVNAME_ONKEY "da9063-onkey" +#define DA9063_DRVNAME_RTC "da9063-rtc" +#define DA9063_DRVNAME_VIBRATION "da9063-vibration" + +enum da9063_models { + PMIC_DA9063 = 0x61, +}; + +/* Interrupts */ +enum da9063_irqs { + DA9063_IRQ_ONKEY = 0, + DA9063_IRQ_ALARM, + DA9063_IRQ_TICK, + DA9063_IRQ_ADC_RDY, + DA9063_IRQ_SEQ_RDY, + DA9063_IRQ_WAKE, + DA9063_IRQ_TEMP, + DA9063_IRQ_COMP_1V2, + DA9063_IRQ_LDO_LIM, + DA9063_IRQ_REG_UVOV, + DA9063_IRQ_VDD_MON, + DA9063_IRQ_WARN, + DA9063_IRQ_GPI0, + DA9063_IRQ_GPI1, + DA9063_IRQ_GPI2, + DA9063_IRQ_GPI3, + DA9063_IRQ_GPI4, + DA9063_IRQ_GPI5, + DA9063_IRQ_GPI6, + DA9063_IRQ_GPI7, + DA9063_IRQ_GPI8, + DA9063_IRQ_GPI9, + DA9063_IRQ_GPI10, + DA9063_IRQ_GPI11, + DA9063_IRQ_GPI12, + DA9063_IRQ_GPI13, + DA9063_IRQ_GPI14, + DA9063_IRQ_GPI15, +}; + +#define DA9063_IRQ_BASE_OFFSET 0 +#define DA9063_NUM_IRQ (DA9063_IRQ_GPI15 + 1 - DA9063_IRQ_BASE_OFFSET) + +struct da9063 { + /* Device */ + struct device *dev; + unsigned short model; + unsigned short revision; + unsigned int flags; + + /* Control interface */ + struct regmap *regmap; + + /* Interrupts */ + int chip_irq; + unsigned int irq_base; + struct regmap_irq_chip_data *regmap_irq; +}; + +int da9063_device_init(struct da9063 *da9063, unsigned int irq); +int da9063_irq_init(struct da9063 *da9063); + +void da9063_device_exit(struct da9063 *da9063); +void da9063_irq_exit(struct da9063 *da9063); + +#endif /* __MFD_DA9063_CORE_H__ */ diff --git a/include/linux/mfd/da9063/pdata.h b/include/linux/mfd/da9063/pdata.h new file mode 100644 index 000000000000..95c8742215a7 --- /dev/null +++ b/include/linux/mfd/da9063/pdata.h @@ -0,0 +1,111 @@ +/* + * Platform configuration options for DA9063 + * + * Copyright 2012 Dialog Semiconductor Ltd. + * + * Author: Michal Hajduk <michal.hajduk@diasemi.com> + * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.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 __MFD_DA9063_PDATA_H__ +#define __MFD_DA9063_PDATA_H__ + +#include <linux/regulator/machine.h> + +/* + * Regulator configuration + */ +/* DA9063 regulator IDs */ +enum { + /* BUCKs */ + DA9063_ID_BCORE1, + DA9063_ID_BCORE2, + DA9063_ID_BPRO, + DA9063_ID_BMEM, + DA9063_ID_BIO, + DA9063_ID_BPERI, + + /* BCORE1 and BCORE2 in merged mode */ + DA9063_ID_BCORES_MERGED, + /* BMEM and BIO in merged mode */ + DA9063_ID_BMEM_BIO_MERGED, + /* When two BUCKs are merged, they cannot be reused separately */ + + /* LDOs */ + DA9063_ID_LDO1, + DA9063_ID_LDO2, + DA9063_ID_LDO3, + DA9063_ID_LDO4, + DA9063_ID_LDO5, + DA9063_ID_LDO6, + DA9063_ID_LDO7, + DA9063_ID_LDO8, + DA9063_ID_LDO9, + DA9063_ID_LDO10, + DA9063_ID_LDO11, +}; + +/* Regulators platform data */ +struct da9063_regulator_data { + int id; + struct regulator_init_data *initdata; +}; + +struct da9063_regulators_pdata { + unsigned n_regulators; + struct da9063_regulator_data *regulator_data; +}; + + +/* + * RGB LED configuration + */ +/* LED IDs for flags in struct led_info. */ +enum { + DA9063_GPIO11_LED, + DA9063_GPIO14_LED, + DA9063_GPIO15_LED, + + DA9063_LED_NUM +}; +#define DA9063_LED_ID_MASK 0x3 + +/* LED polarity for flags in struct led_info. */ +#define DA9063_LED_HIGH_LEVEL_ACTIVE 0x0 +#define DA9063_LED_LOW_LEVEL_ACTIVE 0x4 + + +/* + * General PMIC configuration + */ +/* HWMON ADC channels configuration */ +#define DA9063_FLG_FORCE_IN0_MANUAL_MODE 0x0010 +#define DA9063_FLG_FORCE_IN0_AUTO_MODE 0x0020 +#define DA9063_FLG_FORCE_IN1_MANUAL_MODE 0x0040 +#define DA9063_FLG_FORCE_IN1_AUTO_MODE 0x0080 +#define DA9063_FLG_FORCE_IN2_MANUAL_MODE 0x0100 +#define DA9063_FLG_FORCE_IN2_AUTO_MODE 0x0200 +#define DA9063_FLG_FORCE_IN3_MANUAL_MODE 0x0400 +#define DA9063_FLG_FORCE_IN3_AUTO_MODE 0x0800 + +/* Disable register caching. */ +#define DA9063_FLG_NO_CACHE 0x0008 + +struct da9063; + +/* DA9063 platform data */ +struct da9063_pdata { + int (*init)(struct da9063 *da9063); + int irq_base; + unsigned flags; + struct da9063_regulators_pdata *regulators_pdata; + struct led_platform_data *leds_pdata; +}; + +#endif /* __MFD_DA9063_PDATA_H__ */ diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h new file mode 100644 index 000000000000..5834813fb5f3 --- /dev/null +++ b/include/linux/mfd/da9063/registers.h @@ -0,0 +1,1028 @@ +/* + * Registers definition for DA9063 modules + * + * Copyright 2012 Dialog Semiconductor Ltd. + * + * Author: Michal Hajduk <michal.hajduk@diasemi.com> + * Krystian Garbaciak <krystian.garbaciak@diasemi.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 _DA9063_REG_H +#define _DA9063_REG_H + +#define DA9063_I2C_PAGE_SEL_SHIFT 1 + +#define DA9063_EVENT_REG_NUM 4 +#define DA9210_EVENT_REG_NUM 2 +#define DA9063_EXT_EVENT_REG_NUM (DA9063_EVENT_REG_NUM + \ + DA9210_EVENT_REG_NUM) + +/* Page selection I2C or SPI always in the begining of any page. */ +/* Page 0 : I2C access 0x000 - 0x0FF SPI access 0x000 - 0x07F */ +/* Page 1 : SPI access 0x080 - 0x0FF */ +/* Page 2 : I2C access 0x100 - 0x1FF SPI access 0x100 - 0x17F */ +/* Page 3 : SPI access 0x180 - 0x1FF */ +#define DA9063_REG_PAGE_CON 0x00 + +/* System Control and Event Registers */ +#define DA9063_REG_STATUS_A 0x01 +#define DA9063_REG_STATUS_B 0x02 +#define DA9063_REG_STATUS_C 0x03 +#define DA9063_REG_STATUS_D 0x04 +#define DA9063_REG_FAULT_LOG 0x05 +#define DA9063_REG_EVENT_A 0x06 +#define DA9063_REG_EVENT_B 0x07 +#define DA9063_REG_EVENT_C 0x08 +#define DA9063_REG_EVENT_D 0x09 +#define DA9063_REG_IRQ_MASK_A 0x0A +#define DA9063_REG_IRQ_MASK_B 0x0B +#define DA9063_REG_IRQ_MASK_C 0x0C +#define DA9063_REG_IRQ_MASK_D 0x0D +#define DA9063_REG_CONTROL_A 0x0E +#define DA9063_REG_CONTROL_B 0x0F +#define DA9063_REG_CONTROL_C 0x10 +#define DA9063_REG_CONTROL_D 0x11 +#define DA9063_REG_CONTROL_E 0x12 +#define DA9063_REG_CONTROL_F 0x13 +#define DA9063_REG_PD_DIS 0x14 + +/* GPIO Control Registers */ +#define DA9063_REG_GPIO_0_1 0x15 +#define DA9063_REG_GPIO_2_3 0x16 +#define DA9063_REG_GPIO_4_5 0x17 +#define DA9063_REG_GPIO_6_7 0x18 +#define DA9063_REG_GPIO_8_9 0x19 +#define DA9063_REG_GPIO_10_11 0x1A +#define DA9063_REG_GPIO_12_13 0x1B +#define DA9063_REG_GPIO_14_15 0x1C +#define DA9063_REG_GPIO_MODE_0_7 0x1D +#define DA9063_REG_GPIO_MODE_8_15 0x1E +#define DA9063_REG_GPIO_SWITCH_CONT 0x1F + +/* Regulator Control Registers */ +#define DA9063_REG_BCORE2_CONT 0x20 +#define DA9063_REG_BCORE1_CONT 0x21 +#define DA9063_REG_BPRO_CONT 0x22 +#define DA9063_REG_BMEM_CONT 0x23 +#define DA9063_REG_BIO_CONT 0x24 +#define DA9063_REG_BPERI_CONT 0x25 +#define DA9063_REG_LDO1_CONT 0x26 +#define DA9063_REG_LDO2_CONT 0x27 +#define DA9063_REG_LDO3_CONT 0x28 +#define DA9063_REG_LDO4_CONT 0x29 +#define DA9063_REG_LDO5_CONT 0x2A +#define DA9063_REG_LDO6_CONT 0x2B +#define DA9063_REG_LDO7_CONT 0x2C +#define DA9063_REG_LDO8_CONT 0x2D +#define DA9063_REG_LDO9_CONT 0x2E +#define DA9063_REG_LDO10_CONT 0x2F +#define DA9063_REG_LDO11_CONT 0x30 +#define DA9063_REG_VIB 0x31 +#define DA9063_REG_DVC_1 0x32 +#define DA9063_REG_DVC_2 0x33 + +/* GP-ADC Control Registers */ +#define DA9063_REG_ADC_MAN 0x34 +#define DA9063_REG_ADC_CONT 0x35 +#define DA9063_REG_VSYS_MON 0x36 +#define DA9063_REG_ADC_RES_L 0x37 +#define DA9063_REG_ADC_RES_H 0x38 +#define DA9063_REG_VSYS_RES 0x39 +#define DA9063_REG_ADCIN1_RES 0x3A +#define DA9063_REG_ADCIN2_RES 0x3B +#define DA9063_REG_ADCIN3_RES 0x3C +#define DA9063_REG_MON1_RES 0x3D +#define DA9063_REG_MON2_RES 0x3E +#define DA9063_REG_MON3_RES 0x3F + +/* RTC Calendar and Alarm Registers */ +#define DA9063_REG_COUNT_S 0x40 +#define DA9063_REG_COUNT_MI 0x41 +#define DA9063_REG_COUNT_H 0x42 +#define DA9063_REG_COUNT_D 0x43 +#define DA9063_REG_COUNT_MO 0x44 +#define DA9063_REG_COUNT_Y 0x45 +#define DA9063_REG_ALARM_MI 0x46 +#define DA9063_REG_ALARM_H 0x47 +#define DA9063_REG_ALARM_D 0x48 +#define DA9063_REG_ALARM_MO 0x49 +#define DA9063_REG_ALARM_Y 0x4A +#define DA9063_REG_SECOND_A 0x4B +#define DA9063_REG_SECOND_B 0x4C +#define DA9063_REG_SECOND_C 0x4D +#define DA9063_REG_SECOND_D 0x4E + +/* Sequencer Control Registers */ +#define DA9063_REG_SEQ 0x81 +#define DA9063_REG_SEQ_TIMER 0x82 +#define DA9063_REG_ID_2_1 0x83 +#define DA9063_REG_ID_4_3 0x84 +#define DA9063_REG_ID_6_5 0x85 +#define DA9063_REG_ID_8_7 0x86 +#define DA9063_REG_ID_10_9 0x87 +#define DA9063_REG_ID_12_11 0x88 +#define DA9063_REG_ID_14_13 0x89 +#define DA9063_REG_ID_16_15 0x8A +#define DA9063_REG_ID_18_17 0x8B +#define DA9063_REG_ID_20_19 0x8C +#define DA9063_REG_ID_22_21 0x8D +#define DA9063_REG_ID_24_23 0x8E +#define DA9063_REG_ID_26_25 0x8F +#define DA9063_REG_ID_28_27 0x90 +#define DA9063_REG_ID_30_29 0x91 +#define DA9063_REG_ID_32_31 0x92 +#define DA9063_REG_SEQ_A 0x95 +#define DA9063_REG_SEQ_B 0x96 +#define DA9063_REG_WAIT 0x97 +#define DA9063_REG_EN_32K 0x98 +#define DA9063_REG_RESET 0x99 + +/* Regulator Setting Registers */ +#define DA9063_REG_BUCK_ILIM_A 0x9A +#define DA9063_REG_BUCK_ILIM_B 0x9B +#define DA9063_REG_BUCK_ILIM_C 0x9C +#define DA9063_REG_BCORE2_CFG 0x9D +#define DA9063_REG_BCORE1_CFG 0x9E +#define DA9063_REG_BPRO_CFG 0x9F +#define DA9063_REG_BIO_CFG 0xA0 +#define DA9063_REG_BMEM_CFG 0xA1 +#define DA9063_REG_BPERI_CFG 0xA2 +#define DA9063_REG_VBCORE2_A 0xA3 +#define DA9063_REG_VBCORE1_A 0xA4 +#define DA9063_REG_VBPRO_A 0xA5 +#define DA9063_REG_VBMEM_A 0xA6 +#define DA9063_REG_VBIO_A 0xA7 +#define DA9063_REG_VBPERI_A 0xA8 +#define DA9063_REG_VLDO1_A 0xA9 +#define DA9063_REG_VLDO2_A 0xAA +#define DA9063_REG_VLDO3_A 0xAB +#define DA9063_REG_VLDO4_A 0xAC +#define DA9063_REG_VLDO5_A 0xAD +#define DA9063_REG_VLDO6_A 0xAE +#define DA9063_REG_VLDO7_A 0xAF +#define DA9063_REG_VLDO8_A 0xB0 +#define DA9063_REG_VLDO9_A 0xB1 +#define DA9063_REG_VLDO10_A 0xB2 +#define DA9063_REG_VLDO11_A 0xB3 +#define DA9063_REG_VBCORE2_B 0xB4 +#define DA9063_REG_VBCORE1_B 0xB5 +#define DA9063_REG_VBPRO_B 0xB6 +#define DA9063_REG_VBMEM_B 0xB7 +#define DA9063_REG_VBIO_B 0xB8 +#define DA9063_REG_VBPERI_B 0xB9 +#define DA9063_REG_VLDO1_B 0xBA +#define DA9063_REG_VLDO2_B 0xBB +#define DA9063_REG_VLDO3_B 0xBC +#define DA9063_REG_VLDO4_B 0xBD +#define DA9063_REG_VLDO5_B 0xBE +#define DA9063_REG_VLDO6_B 0xBF +#define DA9063_REG_VLDO7_B 0xC0 +#define DA9063_REG_VLDO8_B 0xC1 +#define DA9063_REG_VLDO9_B 0xC2 +#define DA9063_REG_VLDO10_B 0xC3 +#define DA9063_REG_VLDO11_B 0xC4 + +/* Backup Battery Charger Control Register */ +#define DA9063_REG_BBAT_CONT 0xC5 + +/* GPIO PWM (LED) */ +#define DA9063_REG_GPO11_LED 0xC6 +#define DA9063_REG_GPO14_LED 0xC7 +#define DA9063_REG_GPO15_LED 0xC8 + +/* GP-ADC Threshold Registers */ +#define DA9063_REG_ADC_CFG 0xC9 +#define DA9063_REG_AUTO1_HIGH 0xCA +#define DA9063_REG_AUTO1_LOW 0xCB +#define DA9063_REG_AUTO2_HIGH 0xCC +#define DA9063_REG_AUTO2_LOW 0xCD +#define DA9063_REG_AUTO3_HIGH 0xCE +#define DA9063_REG_AUTO3_LOW 0xCF + +/* DA9063 Configuration registers */ +/* OTP */ +#define DA9063_REG_OPT_COUNT 0x101 +#define DA9063_REG_OPT_ADDR 0x102 +#define DA9063_REG_OPT_DATA 0x103 + +/* Customer Trim and Configuration */ +#define DA9063_REG_T_OFFSET 0x104 +#define DA9063_REG_INTERFACE 0x105 +#define DA9063_REG_CONFIG_A 0x106 +#define DA9063_REG_CONFIG_B 0x107 +#define DA9063_REG_CONFIG_C 0x108 +#define DA9063_REG_CONFIG_D 0x109 +#define DA9063_REG_CONFIG_E 0x10A +#define DA9063_REG_CONFIG_F 0x10B +#define DA9063_REG_CONFIG_G 0x10C +#define DA9063_REG_CONFIG_H 0x10D +#define DA9063_REG_CONFIG_I 0x10E +#define DA9063_REG_CONFIG_J 0x10F +#define DA9063_REG_CONFIG_K 0x110 +#define DA9063_REG_CONFIG_L 0x111 +#define DA9063_REG_MON_REG_1 0x112 +#define DA9063_REG_MON_REG_2 0x113 +#define DA9063_REG_MON_REG_3 0x114 +#define DA9063_REG_MON_REG_4 0x115 +#define DA9063_REG_MON_REG_5 0x116 +#define DA9063_REG_MON_REG_6 0x117 +#define DA9063_REG_TRIM_CLDR 0x118 + +/* General Purpose Registers */ +#define DA9063_REG_GP_ID_0 0x119 +#define DA9063_REG_GP_ID_1 0x11A +#define DA9063_REG_GP_ID_2 0x11B +#define DA9063_REG_GP_ID_3 0x11C +#define DA9063_REG_GP_ID_4 0x11D +#define DA9063_REG_GP_ID_5 0x11E +#define DA9063_REG_GP_ID_6 0x11F +#define DA9063_REG_GP_ID_7 0x120 +#define DA9063_REG_GP_ID_8 0x121 +#define DA9063_REG_GP_ID_9 0x122 +#define DA9063_REG_GP_ID_10 0x123 +#define DA9063_REG_GP_ID_11 0x124 +#define DA9063_REG_GP_ID_12 0x125 +#define DA9063_REG_GP_ID_13 0x126 +#define DA9063_REG_GP_ID_14 0x127 +#define DA9063_REG_GP_ID_15 0x128 +#define DA9063_REG_GP_ID_16 0x129 +#define DA9063_REG_GP_ID_17 0x12A +#define DA9063_REG_GP_ID_18 0x12B +#define DA9063_REG_GP_ID_19 0x12C + +/* Chip ID and variant */ +#define DA9063_REG_CHIP_ID 0x181 +#define DA9063_REG_CHIP_VARIANT 0x182 + +/* + * PMIC registers bits + */ +/* DA9063_REG_PAGE_CON (addr=0x00) */ +#define DA9063_PEG_PAGE_SHIFT 0 +#define DA9063_REG_PAGE_MASK 0x07 +#define DA9063_REG_PAGE0 0x00 +#define DA9063_REG_PAGE2 0x02 +#define DA9063_PAGE_WRITE_MODE 0x00 +#define DA9063_REPEAT_WRITE_MODE 0x40 +#define DA9063_PAGE_REVERT 0x80 + +/* DA9063_REG_STATUS_A (addr=0x01) */ +#define DA9063_NONKEY 0x01 +#define DA9063_WAKE 0x02 +#define DA9063_DVC_BUSY 0x04 +#define DA9063_COMP_1V2 0x08 + +/* DA9063_REG_STATUS_B (addr=0x02) */ +#define DA9063_GPI0 0x01 +#define DA9063_GPI1 0x02 +#define DA9063_GPI2 0x04 +#define DA9063_GPI3 0x08 +#define DA9063_GPI4 0x10 +#define DA9063_GPI5 0x20 +#define DA9063_GPI6 0x40 +#define DA9063_GPI7 0x80 + +/* DA9063_REG_STATUS_C (addr=0x03) */ +#define DA9063_GPI8 0x01 +#define DA9063_GPI9 0x02 +#define DA9063_GPI10 0x04 +#define DA9063_GPI11 0x08 +#define DA9063_GPI12 0x10 +#define DA9063_GPI13 0x20 +#define DA9063_GPI14 0x40 +#define DA9063_GPI15 0x80 + +/* DA9063_REG_STATUS_D (addr=0x04) */ +#define DA9063_LDO3_LIM 0x08 +#define DA9063_LDO4_LIM 0x10 +#define DA9063_LDO7_LIM 0x20 +#define DA9063_LDO8_LIM 0x40 +#define DA9063_LDO11_LIM 0x80 + +/* DA9063_REG_FAULT_LOG (addr=0x05) */ +#define DA9063_TWD_ERROR 0x01 +#define DA9063_POR 0x02 +#define DA9063_VDD_FAULT 0x04 +#define DA9063_VDD_START 0x08 +#define DA9063_TEMP_CRIT 0x10 +#define DA9063_KEY_RESET 0x20 +#define DA9063_NSHUTDOWN 0x40 +#define DA9063_WAIT_SHUT 0x80 + +/* DA9063_REG_EVENT_A (addr=0x06) */ +#define DA9063_E_NONKEY 0x01 +#define DA9063_E_ALARM 0x02 +#define DA9063_E_TICK 0x04 +#define DA9063_E_ADC_RDY 0x08 +#define DA9063_E_SEQ_RDY 0x10 +#define DA9063_EVENTS_B 0x20 +#define DA9063_EVENTS_C 0x40 +#define DA9063_EVENTS_D 0x80 + +/* DA9063_REG_EVENT_B (addr=0x07) */ +#define DA9063_E_WAKE 0x01 +#define DA9063_E_TEMP 0x02 +#define DA9063_E_COMP_1V2 0x04 +#define DA9063_E_LDO_LIM 0x08 +#define DA9063_E_REG_UVOV 0x10 +#define DA9063_E_DVC_RDY 0x20 +#define DA9063_E_VDD_MON 0x40 +#define DA9063_E_VDD_WARN 0x80 + +/* DA9063_REG_EVENT_C (addr=0x08) */ +#define DA9063_E_GPI0 0x01 +#define DA9063_E_GPI1 0x02 +#define DA9063_E_GPI2 0x04 +#define DA9063_E_GPI3 0x08 +#define DA9063_E_GPI4 0x10 +#define DA9063_E_GPI5 0x20 +#define DA9063_E_GPI6 0x40 +#define DA9063_E_GPI7 0x80 + +/* DA9063_REG_EVENT_D (addr=0x09) */ +#define DA9063_E_GPI8 0x01 +#define DA9063_E_GPI9 0x02 +#define DA9063_E_GPI10 0x04 +#define DA9063_E_GPI11 0x08 +#define DA9063_E_GPI12 0x10 +#define DA9063_E_GPI13 0x20 +#define DA9063_E_GPI14 0x40 +#define DA9063_E_GPI15 0x80 + +/* DA9063_REG_IRQ_MASK_A (addr=0x0A) */ +#define DA9063_M_ONKEY 0x01 +#define DA9063_M_ALARM 0x02 +#define DA9063_M_TICK 0x04 +#define DA9063_M_ADC_RDY 0x08 +#define DA9063_M_SEQ_RDY 0x10 + +/* DA9063_REG_IRQ_MASK_B (addr=0x0B) */ +#define DA9063_M_WAKE 0x01 +#define DA9063_M_TEMP 0x02 +#define DA9063_M_COMP_1V2 0x04 +#define DA9063_M_LDO_LIM 0x08 +#define DA9063_M_UVOV 0x10 +#define DA9063_M_DVC_RDY 0x20 +#define DA9063_M_VDD_MON 0x40 +#define DA9063_M_VDD_WARN 0x80 + +/* DA9063_REG_IRQ_MASK_C (addr=0x0C) */ +#define DA9063_M_GPI0 0x01 +#define DA9063_M_GPI1 0x02 +#define DA9063_M_GPI2 0x04 +#define DA9063_M_GPI3 0x08 +#define DA9063_M_GPI4 0x10 +#define DA9063_M_GPI5 0x20 +#define DA9063_M_GPI6 0x40 +#define DA9063_M_GPI7 0x80 + +/* DA9063_REG_IRQ_MASK_D (addr=0x0D) */ +#define DA9063_M_GPI8 0x01 +#define DA9063_M_GPI9 0x02 +#define DA9063_M_GPI10 0x04 +#define DA9063_M_GPI11 0x08 +#define DA9063_M_GPI12 0x10 +#define DA9063_M_GPI13 0x20 +#define DA9063_M_GPI14 0x40 +#define DA9063_M_GPI15 0x80 + +/* DA9063_REG_CONTROL_A (addr=0x0E) */ +#define DA9063_SYSTEM_EN 0x01 +#define DA9063_POWER_EN 0x02 +#define DA9063_POWER1_EN 0x04 +#define DA9063_STANDBY 0x08 +#define DA9063_M_SYSTEM_EN 0x10 +#define DA9063_M_POWER_EN 0x20 +#define DA9063_M_POWER1_EN 0x40 +#define DA9063_CP_EN 0x80 + +/* DA9063_REG_CONTROL_B (addr=0x0F) */ +#define DA9063_CHG_SEL 0x01 +#define DA9063_WATCHDOG_PD 0x02 +#define DA9063_NRES_MODE 0x08 +#define DA9063_NONKEY_LOCK 0x10 + +/* DA9063_REG_CONTROL_C (addr=0x10) */ +#define DA9063_DEBOUNCING_MASK 0x07 +#define DA9063_DEBOUNCING_OFF 0x0 +#define DA9063_DEBOUNCING_0MS1 0x1 +#define DA9063_DEBOUNCING_1MS 0x2 +#define DA9063_DEBOUNCING_10MS24 0x3 +#define DA9063_DEBOUNCING_51MS2 0x4 +#define DA9063_DEBOUNCING_256MS 0x5 +#define DA9063_DEBOUNCING_512MS 0x6 +#define DA9063_DEBOUNCING_1024MS 0x7 + +#define DA9063_AUTO_BOOT 0x08 +#define DA9063_OTPREAD_EN 0x10 +#define DA9063_SLEW_RATE_MASK 0x60 +#define DA9063_SLEW_RATE_4US 0x00 +#define DA9063_SLEW_RATE_3US 0x20 +#define DA9063_SLEW_RATE_1US 0x40 +#define DA9063_SLEW_RATE_0US5 0x60 +#define DA9063_DEF_SUPPLY 0x80 + +/* DA9063_REG_CONTROL_D (addr=0x11) */ +#define DA9063_TWDSCALE_MASK 0x07 +#define DA9063_BLINK_FRQ_MASK 0x38 +#define DA9063_BLINK_FRQ_OFF 0x00 +#define DA9063_BLINK_FRQ_1S0 0x08 +#define DA9063_BLINK_FRQ_2S0 0x10 +#define DA9063_BLINK_FRQ_4S0 0x18 +#define DA9063_BLINK_FRQ_0S18 0x20 +#define DA9063_BLINK_FRQ_2S0_VDD 0x28 +#define DA9063_BLINK_FRQ_4S0_VDD 0x30 +#define DA9063_BLINK_FRQ_0S18_VDD 0x38 + +#define DA9063_BLINK_DUR_MASK 0xC0 +#define DA9063_BLINK_DUR_10MS 0x00 +#define DA9063_BLINK_DUR_20MS 0x40 +#define DA9063_BLINK_DUR_40MS 0x80 +#define DA9063_BLINK_DUR_20MSDBL 0xC0 + +/* DA9063_REG_CONTROL_E (addr=0x12) */ +#define DA9063_RTC_MODE_PD 0x01 +#define DA9063_RTC_MODE_SD 0x02 +#define DA9063_RTC_EN 0x04 +#define DA9063_ECO_MODE 0x08 +#define DA9063_PM_FB1_PIN 0x10 +#define DA9063_PM_FB2_PIN 0x20 +#define DA9063_PM_FB3_PIN 0x40 +#define DA9063_V_LOCK 0x80 + +/* DA9063_REG_CONTROL_F (addr=0x13) */ +#define DA9063_WATCHDOG 0x01 +#define DA9063_SHUTDOWN 0x02 +#define DA9063_WAKE_UP 0x04 + +/* DA9063_REG_PD_DIS (addr=0x14) */ +#define DA9063_GPI_DIS 0x01 +#define DA9063_GPADC_PAUSE 0x02 +#define DA9063_PMIF_DIS 0x04 +#define DA9063_HS2WIRE_DIS 0x08 +#define DA9063_BBAT_DIS 0x20 +#define DA9063_OUT_32K_PAUSE 0x40 +#define DA9063_PMCONT_DIS 0x80 + +/* DA9063_REG_GPIO_0_1 (addr=0x15) */ +#define DA9063_GPIO0_PIN_MASK 0x03 +#define DA9063_GPIO0_PIN_ADCIN1 0x00 +#define DA9063_GPIO0_PIN_GPI 0x01 +#define DA9063_GPIO0_PIN_GPO_OD 0x02 +#define DA9063_GPIO0_PIN_GPO 0x03 +#define DA9063_GPIO0_TYPE 0x04 +#define DA9063_GPIO0_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO0_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO0_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO0_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO0_NO_WAKEUP 0x08 +#define DA9063_GPIO1_PIN_MASK 0x30 +#define DA9063_GPIO1_PIN_ADCIN2_COMP 0x00 +#define DA9063_GPIO1_PIN_GPI 0x10 +#define DA9063_GPIO1_PIN_GPO_OD 0x20 +#define DA9063_GPIO1_PIN_GPO 0x30 +#define DA9063_GPIO1_TYPE 0x40 +#define DA9063_GPIO1_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO1_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO1_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO1_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO1_NO_WAKEUP 0x80 + +/* DA9063_REG_GPIO_2_3 (addr=0x16) */ +#define DA9063_GPIO2_PIN_MASK 0x03 +#define DA9063_GPIO2_PIN_ADCIN3 0x00 +#define DA9063_GPIO2_PIN_GPI 0x01 +#define DA9063_GPIO2_PIN_GPO_PSS 0x02 +#define DA9063_GPIO2_PIN_GPO 0x03 +#define DA9063_GPIO2_TYPE 0x04 +#define DA9063_GPIO2_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO2_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO2_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO2_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO2_NO_WAKEUP 0x08 +#define DA9063_GPIO3_PIN_MASK 0x30 +#define DA9063_GPIO3_PIN_CORE_SW_G 0x00 +#define DA9063_GPIO3_PIN_GPI 0x10 +#define DA9063_GPIO3_PIN_GPO_OD 0x20 +#define DA9063_GPIO3_PIN_GPO 0x30 +#define DA9063_GPIO3_TYPE 0x40 +#define DA9063_GPIO3_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO3_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO3_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO3_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO3_NO_WAKEUP 0x80 + +/* DA9063_REG_GPIO_4_5 (addr=0x17) */ +#define DA9063_GPIO4_PIN_MASK 0x03 +#define DA9063_GPIO4_PIN_CORE_SW_S 0x00 +#define DA9063_GPIO4_PIN_GPI 0x01 +#define DA9063_GPIO4_PIN_GPO_OD 0x02 +#define DA9063_GPIO4_PIN_GPO 0x03 +#define DA9063_GPIO4_TYPE 0x04 +#define DA9063_GPIO4_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO4_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO4_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO4_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO4_NO_WAKEUP 0x08 +#define DA9063_GPIO5_PIN_MASK 0x30 +#define DA9063_GPIO5_PIN_PERI_SW_G 0x00 +#define DA9063_GPIO5_PIN_GPI 0x10 +#define DA9063_GPIO5_PIN_GPO_OD 0x20 +#define DA9063_GPIO5_PIN_GPO 0x30 +#define DA9063_GPIO5_TYPE 0x40 +#define DA9063_GPIO5_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO5_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO5_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO5_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO5_NO_WAKEUP 0x80 + +/* DA9063_REG_GPIO_6_7 (addr=0x18) */ +#define DA9063_GPIO6_PIN_MASK 0x03 +#define DA9063_GPIO6_PIN_PERI_SW_S 0x00 +#define DA9063_GPIO6_PIN_GPI 0x01 +#define DA9063_GPIO6_PIN_GPO_OD 0x02 +#define DA9063_GPIO6_PIN_GPO 0x03 +#define DA9063_GPIO6_TYPE 0x04 +#define DA9063_GPIO6_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO6_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO6_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO6_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO6_NO_WAKEUP 0x08 +#define DA9063_GPIO7_PIN_MASK 0x30 +#define DA9063_GPIO7_PIN_GPI 0x10 +#define DA9063_GPIO7_PIN_GPO_PSS 0x20 +#define DA9063_GPIO7_PIN_GPO 0x30 +#define DA9063_GPIO7_TYPE 0x40 +#define DA9063_GPIO7_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO7_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO7_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO7_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO7_NO_WAKEUP 0x80 + +/* DA9063_REG_GPIO_8_9 (addr=0x19) */ +#define DA9063_GPIO8_PIN_MASK 0x03 +#define DA9063_GPIO8_PIN_GPI_SYS_EN 0x00 +#define DA9063_GPIO8_PIN_GPI 0x01 +#define DA9063_GPIO8_PIN_GPO_PSS 0x02 +#define DA9063_GPIO8_PIN_GPO 0x03 +#define DA9063_GPIO8_TYPE 0x04 +#define DA9063_GPIO8_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO8_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO8_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO8_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO8_NO_WAKEUP 0x08 +#define DA9063_GPIO9_PIN_MASK 0x30 +#define DA9063_GPIO9_PIN_GPI_PWR_EN 0x00 +#define DA9063_GPIO9_PIN_GPI 0x10 +#define DA9063_GPIO9_PIN_GPO_PSS 0x20 +#define DA9063_GPIO9_PIN_GPO 0x30 +#define DA9063_GPIO9_TYPE 0x40 +#define DA9063_GPIO9_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO9_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO9_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO9_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO9_NO_WAKEUP 0x80 + +/* DA9063_REG_GPIO_10_11 (addr=0x1A) */ +#define DA9063_GPIO10_PIN_MASK 0x03 +#define DA9063_GPIO10_PIN_GPI_PWR1_EN 0x00 +#define DA9063_GPIO10_PIN_GPI 0x01 +#define DA9063_GPIO10_PIN_GPO_OD 0x02 +#define DA9063_GPIO10_PIN_GPO 0x03 +#define DA9063_GPIO10_TYPE 0x04 +#define DA9063_GPIO10_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO10_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO10_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO10_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO10_NO_WAKEUP 0x08 +#define DA9063_GPIO11_PIN_MASK 0x30 +#define DA9063_GPIO11_PIN_GPO_OD 0x00 +#define DA9063_GPIO11_PIN_GPI 0x10 +#define DA9063_GPIO11_PIN_GPO_PSS 0x20 +#define DA9063_GPIO11_PIN_GPO 0x30 +#define DA9063_GPIO11_TYPE 0x40 +#define DA9063_GPIO11_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO11_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO11_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO11_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO11_NO_WAKEUP 0x80 + +/* DA9063_REG_GPIO_12_13 (addr=0x1B) */ +#define DA9063_GPIO12_PIN_MASK 0x03 +#define DA9063_GPIO12_PIN_NVDDFLT_OUT 0x00 +#define DA9063_GPIO12_PIN_GPI 0x01 +#define DA9063_GPIO12_PIN_VSYSMON_OUT 0x02 +#define DA9063_GPIO12_PIN_GPO 0x03 +#define DA9063_GPIO12_TYPE 0x04 +#define DA9063_GPIO12_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO12_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO12_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO12_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO12_NO_WAKEUP 0x08 +#define DA9063_GPIO13_PIN_MASK 0x30 +#define DA9063_GPIO13_PIN_GPFB1_OUT 0x00 +#define DA9063_GPIO13_PIN_GPI 0x10 +#define DA9063_GPIO13_PIN_GPFB1_OUTOD 0x20 +#define DA9063_GPIO13_PIN_GPO 0x30 +#define DA9063_GPIO13_TYPE 0x40 +#define DA9063_GPIO13_TYPE_GPFB1_OUT 0x00 +#define DA9063_GPIO13_TYPE_GPI 0x00 +#define DA9063_GPIO13_TYPE_GPFB1_OUTOD 0x04 +#define DA9063_GPIO13_TYPE_GPO 0x04 +#define DA9063_GPIO13_NO_WAKEUP 0x80 + +/* DA9063_REG_GPIO_14_15 (addr=0x1C) */ +#define DA9063_GPIO14_PIN_MASK 0x03 +#define DA9063_GPIO14_PIN_GPO_OD 0x00 +#define DA9063_GPIO14_PIN_GPI 0x01 +#define DA9063_GPIO14_PIN_HS2DATA 0x02 +#define DA9063_GPIO14_PIN_GPO 0x03 +#define DA9063_GPIO14_TYPE 0x04 +#define DA9063_GPIO14_TYPE_GPI_ACT_LOW 0x00 +#define DA9063_GPIO14_TYPE_GPO_VDD_IO1 0x00 +#define DA9063_GPIO14_TYPE_GPI_ACT_HIGH 0x04 +#define DA9063_GPIO14_TYPE_GPO_VDD_IO2 0x04 +#define DA9063_GPIO14_NO_WAKEUP 0x08 +#define DA9063_GPIO15_PIN_MASK 0x30 +#define DA9063_GPIO15_PIN_GPO_OD 0x00 +#define DA9063_GPIO15_PIN_GPI 0x10 +#define DA9063_GPIO15_PIN_GPO 0x30 +#define DA9063_GPIO15_TYPE 0x40 +#define DA9063_GPIO15_TYPE_GPFB1_OUT 0x00 +#define DA9063_GPIO15_TYPE_GPI 0x00 +#define DA9063_GPIO15_TYPE_GPFB1_OUTOD 0x04 +#define DA9063_GPIO15_TYPE_GPO 0x04 +#define DA9063_GPIO15_NO_WAKEUP 0x80 + +/* DA9063_REG_GPIO_MODE_0_7 (addr=0x1D) */ +#define DA9063_GPIO0_MODE 0x01 +#define DA9063_GPIO1_MODE 0x02 +#define DA9063_GPIO2_MODE 0x04 +#define DA9063_GPIO3_MODE 0x08 +#define DA9063_GPIO4_MODE 0x10 +#define DA9063_GPIO5_MODE 0x20 +#define DA9063_GPIO6_MODE 0x40 +#define DA9063_GPIO7_MODE 0x80 + +/* DA9063_REG_GPIO_MODE_8_15 (addr=0x1E) */ +#define DA9063_GPIO8_MODE 0x01 +#define DA9063_GPIO9_MODE 0x02 +#define DA9063_GPIO10_MODE 0x04 +#define DA9063_GPIO11_MODE 0x08 +#define DA9063_GPIO11_MODE_LED_ACT_HIGH 0x00 +#define DA9063_GPIO11_MODE_LED_ACT_LOW 0x08 +#define DA9063_GPIO12_MODE 0x10 +#define DA9063_GPIO13_MODE 0x20 +#define DA9063_GPIO14_MODE 0x40 +#define DA9063_GPIO14_MODE_LED_ACT_HIGH 0x00 +#define DA9063_GPIO14_MODE_LED_ACT_LOW 0x40 +#define DA9063_GPIO15_MODE 0x80 +#define DA9063_GPIO15_MODE_LED_ACT_HIGH 0x00 +#define DA9063_GPIO15_MODE_LED_ACT_LOW 0x80 + +/* DA9063_REG_SWITCH_CONT (addr=0x1F) */ +#define DA9063_CORE_SW_GPI_MASK 0x03 +#define DA9063_CORE_SW_GPI_OFF 0x00 +#define DA9063_CORE_SW_GPI_GPIO1 0x01 +#define DA9063_CORE_SW_GPI_GPIO2 0x02 +#define DA9063_CORE_SW_GPI_GPIO13 0x03 +#define DA9063_PERI_SW_GPI_MASK 0x0C +#define DA9063_PERI_SW_GPI_OFF 0x00 +#define DA9063_PERI_SW_GPI_GPIO1 0x04 +#define DA9063_PERI_SW_GPI_GPIO2 0x08 +#define DA9063_PERI_SW_GPI_GPIO13 0x0C +#define DA9063_SWITCH_SR_MASK 0x30 +#define DA9063_SWITCH_SR_1MV 0x00 +#define DA9063_SWITCH_SR_5MV 0x10 +#define DA9063_SWITCH_SR_10MV 0x20 +#define DA9063_SWITCH_SR_50MV 0x30 +#define DA9063_SWITCH_SR_DIS 0x40 +#define DA9063_CP_EN_MODE 0x80 + +/* DA9063_REGL_Bxxxx_CONT common bits (addr=0x20-0x25) */ +#define DA9063_BUCK_EN 0x01 +#define DA9063_BUCK_GPI_MASK 0x06 +#define DA9063_BUCK_GPI_OFF 0x00 +#define DA9063_BUCK_GPI_GPIO1 0x02 +#define DA9063_BUCK_GPI_GPIO2 0x04 +#define DA9063_BUCK_GPI_GPIO13 0x06 +#define DA9063_BUCK_CONF 0x08 +#define DA9063_VBUCK_GPI_MASK 0x60 +#define DA9063_VBUCK_GPI_OFF 0x00 +#define DA9063_VBUCK_GPI_GPIO1 0x20 +#define DA9063_VBUCK_GPI_GPIO2 0x40 +#define DA9063_VBUCK_GPI_GPIO13 0x60 + +/* DA9063_REG_BCORE1_CONT specific bits (addr=0x21) */ +#define DA9063_CORE_SW_EN 0x10 +#define DA9063_CORE_SW_CONF 0x80 + +/* DA9063_REG_BPERI_CONT specific bits (addr=0x25) */ +#define DA9063_PERI_SW_EN 0x10 +#define DA9063_PERI_SW_CONF 0x80 + +/* DA9063_REG_LDOx_CONT common bits (addr=0x26-0x30) */ +#define DA9063_LDO_EN 0x01 +#define DA9063_LDO_GPI_MASK 0x06 +#define DA9063_LDO_GPI_OFF 0x00 +#define DA9063_LDO_GPI_GPIO1 0x02 +#define DA9063_LDO_GPI_GPIO2 0x04 +#define DA9063_LDO_GPI_GPIO13 0x06 +#define DA9063_LDO_PD_DIS 0x08 +#define DA9063_VLDO_GPI_MASK 0x60 +#define DA9063_VLDO_GPI_OFF 0x00 +#define DA9063_VLDO_GPI_GPIO1 0x20 +#define DA9063_VLDO_GPI_GPIO2 0x40 +#define DA9063_VLDO_GPI_GPIO13 0x60 +#define DA9063_LDO_CONF 0x80 + +/* DA9063_REG_LDO5_CONT specific bits (addr=0x2A) */ +#define DA9063_VLDO5_SEL 0x10 + +/* DA9063_REG_LDO6_CONT specific bits (addr=0x2B) */ +#define DA9063_VLDO6_SEL 0x10 + +/* DA9063_REG_LDO7_CONT specific bits (addr=0x2C) */ +#define DA9063_VLDO7_SEL 0x10 + +/* DA9063_REG_LDO8_CONT specific bits (addr=0x2D) */ +#define DA9063_VLDO8_SEL 0x10 + +/* DA9063_REG_LDO9_CONT specific bits (addr=0x2E) */ +#define DA9063_VLDO9_SEL 0x10 + +/* DA9063_REG_LDO10_CONT specific bits (addr=0x2F) */ +#define DA9063_VLDO10_SEL 0x10 + +/* DA9063_REG_LDO11_CONT specific bits (addr=0x30) */ +#define DA9063_VLDO11_SEL 0x10 + +/* DA9063_REG_VIB (addr=0x31) */ +#define DA9063_VIB_SET_MASK 0x3F +#define DA9063_VIB_SET_OFF 0 +#define DA9063_VIB_SET_MAX 0x3F + +/* DA9063_REG_DVC_1 (addr=0x32) */ +#define DA9063_VBCORE1_SEL 0x01 +#define DA9063_VBCORE2_SEL 0x02 +#define DA9063_VBPRO_SEL 0x04 +#define DA9063_VBMEM_SEL 0x08 +#define DA9063_VBPERI_SEL 0x10 +#define DA9063_VLDO1_SEL 0x20 +#define DA9063_VLDO2_SEL 0x40 +#define DA9063_VLDO3_SEL 0x80 + +/* DA9063_REG_DVC_2 (addr=0x33) */ +#define DA9063_VBIO_SEL 0x01 +#define DA9063_VLDO4_SEL 0x80 + +/* DA9063_REG_ADC_MAN (addr=0x34) */ +#define DA9063_ADC_MUX_MASK 0x0F +#define DA9063_ADC_MUX_VSYS 0x00 +#define DA9063_ADC_MUX_ADCIN1 0x01 +#define DA9063_ADC_MUX_ADCIN2 0x02 +#define DA9063_ADC_MUX_ADCIN3 0x03 +#define DA9063_ADC_MUX_T_SENSE 0x04 +#define DA9063_ADC_MUX_VBBAT 0x05 +#define DA9063_ADC_MUX_LDO_G1 0x08 +#define DA9063_ADC_MUX_LDO_G2 0x09 +#define DA9063_ADC_MUX_LDO_G3 0x0A +#define DA9063_ADC_MAN 0x10 +#define DA9063_ADC_MODE 0x20 + +/* DA9063_REG_ADC_CONT (addr=0x35) */ +#define DA9063_ADC_AUTO_VSYS_EN 0x01 +#define DA9063_ADC_AUTO_AD1_EN 0x02 +#define DA9063_ADC_AUTO_AD2_EN 0x04 +#define DA9063_ADC_AUTO_AD3_EN 0x08 +#define DA9063_ADC_AD1_ISRC_EN 0x10 +#define DA9063_ADC_AD2_ISRC_EN 0x20 +#define DA9063_ADC_AD3_ISRC_EN 0x40 +#define DA9063_COMP1V2_EN 0x80 + +/* DA9063_REG_VSYS_MON (addr=0x36) */ +#define DA9063_VSYS_VAL_MASK 0xFF +#define DA9063_VSYS_VAL_BASE 0x00 + +/* DA9063_REG_ADC_RES_L (addr=0x37) */ +#define DA9063_ADC_RES_L_BITS 2 +#define DA9063_ADC_RES_L_MASK 0xC0 + +/* DA9063_REG_ADC_RES_H (addr=0x38) */ +#define DA9063_ADC_RES_M_BITS 8 +#define DA9063_ADC_RES_M_MASK 0xFF + +/* DA9063_REG_(xxx_RES/ADC_RES_H) (addr=0x39-0x3F) */ +#define DA9063_ADC_VAL_MASK 0xFF + +/* DA9063_REG_COUNT_S (addr=0x40) */ +#define DA9063_RTC_READ 0x80 +#define DA9063_COUNT_SEC_MASK 0x3F + +/* DA9063_REG_COUNT_MI (addr=0x41) */ +#define DA9063_COUNT_MIN_MASK 0x3F + +/* DA9063_REG_COUNT_H (addr=0x42) */ +#define DA9063_COUNT_HOUR_MASK 0x1F + +/* DA9063_REG_COUNT_D (addr=0x43) */ +#define DA9063_COUNT_DAY_MASK 0x1F + +/* DA9063_REG_COUNT_MO (addr=0x44) */ +#define DA9063_COUNT_MONTH_MASK 0x0F + +/* DA9063_REG_COUNT_Y (addr=0x45) */ +#define DA9063_COUNT_YEAR_MASK 0x3F +#define DA9063_MONITOR 0x40 + +/* DA9063_REG_ALARM_MI (addr=0x46) */ +#define DA9063_ALARM_STATUS_ALARM 0x80 +#define DA9063_ALARM_STATUS_TICK 0x40 +#define DA9063_ALARM_MIN_MASK 0x3F + +/* DA9063_REG_ALARM_H (addr=0x47) */ +#define DA9063_ALARM_HOUR_MASK 0x1F + +/* DA9063_REG_ALARM_D (addr=0x48) */ +#define DA9063_ALARM_DAY_MASK 0x1F + +/* DA9063_REG_ALARM_MO (addr=0x49) */ +#define DA9063_TICK_WAKE 0x20 +#define DA9063_TICK_TYPE 0x10 +#define DA9063_TICK_TYPE_SEC 0x00 +#define DA9063_TICK_TYPE_MIN 0x10 +#define DA9063_ALARM_MONTH_MASK 0x0F + +/* DA9063_REG_ALARM_Y (addr=0x4A) */ +#define DA9063_TICK_ON 0x80 +#define DA9063_ALARM_ON 0x40 +#define DA9063_ALARM_YEAR_MASK 0x3F + +/* DA9063_REG_WAIT (addr=0x97)*/ +#define DA9063_REG_WAIT_TIME_MASK 0xF +#define DA9063_WAIT_TIME_0_US 0x0 +#define DA9063_WAIT_TIME_512_US 0x1 +#define DA9063_WAIT_TIME_1_MS 0x2 +#define DA9063_WAIT_TIME_2_MS 0x3 +#define DA9063_WAIT_TIME_4_1_MS 0x4 +#define DA9063_WAIT_TIME_8_2_MS 0x5 +#define DA9063_WAIT_TIME_16_4_MS 0x6 +#define DA9063_WAIT_TIME_32_8_MS 0x7 +#define DA9063_WAIT_TIME_65_5_MS 0x8 +#define DA9063_WAIT_TIME_128_MS 0x9 +#define DA9063_WAIT_TIME_256_MS 0xA +#define DA9063_WAIT_TIME_512_MS 0xB +#define DA9063_WAIT_TIME_1_S 0xC +#define DA9063_WAIT_TIME_2_1_S 0xD + +/* DA9063_REG_EN_32K (addr=0x98)*/ +#define DA9063_STABILIZ_TIME_MASK 0x7 +#define DA9063_CRYSTAL 0x08 +#define DA9063_DELAY_MODE 0x10 +#define DA9063_OUT_CLOCK 0x20 +#define DA9063_RTC_CLOCK 0x40 +#define DA9063_OUT_32K_EN 0x80 + +/* DA9063_REG_CHIP_VARIANT */ +#define DA9063_CHIP_VARIANT_SHIFT 4 + +/* DA9063_REG_BUCK_ILIM_A (addr=0x9A) */ +#define DA9063_BIO_ILIM_MASK 0x0F +#define DA9063_BMEM_ILIM_MASK 0xF0 + +/* DA9063_REG_BUCK_ILIM_B (addr=0x9B) */ +#define DA9063_BPRO_ILIM_MASK 0x0F +#define DA9063_BPERI_ILIM_MASK 0xF0 + +/* DA9063_REG_BUCK_ILIM_C (addr=0x9C) */ +#define DA9063_BCORE1_ILIM_MASK 0x0F +#define DA9063_BCORE2_ILIM_MASK 0xF0 + +/* DA9063_REG_Bxxxx_CFG common bits (addr=0x9D-0xA2) */ +#define DA9063_BUCK_FB_MASK 0x07 +#define DA9063_BUCK_PD_DIS_SHIFT 5 +#define DA9063_BUCK_MODE_MASK 0xC0 +#define DA9063_BUCK_MODE_MANUAL 0x00 +#define DA9063_BUCK_MODE_SLEEP 0x40 +#define DA9063_BUCK_MODE_SYNC 0x80 +#define DA9063_BUCK_MODE_AUTO 0xC0 + +/* DA9063_REG_BPRO_CFG (addr=0x9F) */ +#define DA9063_BPRO_VTTR_EN 0x08 +#define DA9063_BPRO_VTT_EN 0x10 + +/* DA9063_REG_VBxxxx_A/B (addr=0xA3-0xA8, 0xB4-0xB9) */ +#define DA9063_VBUCK_MASK 0x7F +#define DA9063_VBUCK_BIAS 0 +#define DA9063_BUCK_SL 0x80 + +/* DA9063_REG_VLDOx_A/B (addr=0xA9-0x3, 0xBA-0xC4) */ +#define DA9063_LDO_SL 0x80 + +/* DA9063_REG_VLDO1_A/B (addr=0xA9, 0xBA) */ +#define DA9063_VLDO1_MASK 0x3F +#define DA9063_VLDO1_BIAS 0 + +/* DA9063_REG_VLDO2_A/B (addr=0xAA, 0xBB) */ +#define DA9063_VLDO2_MASK 0x3F +#define DA9063_VLDO2_BIAS 0 + +/* DA9063_REG_VLDO3_A/B (addr=0xAB, 0xBC) */ +#define DA9063_VLDO3_MASK 0x7F +#define DA9063_VLDO3_BIAS 0 + +/* DA9063_REG_VLDO4_A/B (addr=0xAC, 0xBD) */ +#define DA9063_VLDO4_MASK 0x7F +#define DA9063_VLDO4_BIAS 0 + +/* DA9063_REG_VLDO5_A/B (addr=0xAD, 0xBE) */ +#define DA9063_VLDO5_MASK 0x3F +#define DA9063_VLDO5_BIAS 2 + +/* DA9063_REG_VLDO6_A/B (addr=0xAE, 0xBF) */ +#define DA9063_VLDO6_MASK 0x3F +#define DA9063_VLDO6_BIAS 2 + +/* DA9063_REG_VLDO7_A/B (addr=0xAF, 0xC0) */ +#define DA9063_VLDO7_MASK 0x3F +#define DA9063_VLDO7_BIAS 2 + +/* DA9063_REG_VLDO8_A/B (addr=0xB0, 0xC1) */ +#define DA9063_VLDO8_MASK 0x3F +#define DA9063_VLDO8_BIAS 2 + +/* DA9063_REG_VLDO9_A/B (addr=0xB1, 0xC2) */ +#define DA9063_VLDO9_MASK 0x3F +#define DA9063_VLDO9_BIAS 3 + +/* DA9063_REG_VLDO10_A/B (addr=0xB2, 0xC3) */ +#define DA9063_VLDO10_MASK 0x3F +#define DA9063_VLDO10_BIAS 2 + +/* DA9063_REG_VLDO11_A/B (addr=0xB3, 0xC4) */ +#define DA9063_VLDO11_MASK 0x3F +#define DA9063_VLDO11_BIAS 2 + +/* DA9063_REG_GPO11_LED (addr=0xC6) */ +/* DA9063_REG_GPO14_LED (addr=0xC7) */ +/* DA9063_REG_GPO15_LED (addr=0xC8) */ +#define DA9063_GPIO_DIM 0x80 +#define DA9063_GPIO_PWM_MASK 0x7F + +/* DA9063_REG_CONFIG_H (addr=0x10D) */ +#define DA9063_PWM_CLK_MASK 0x01 +#define DA9063_PWM_CLK_PWM2MHZ 0x00 +#define DA9063_PWM_CLK_PWM1MHZ 0x01 +#define DA9063_LDO8_MODE_MASK 0x02 +#define DA9063_LDO8_MODE_LDO 0 +#define DA9063_LDO8_MODE_VIBR 0x02 +#define DA9063_MERGE_SENSE_MASK 0x04 +#define DA9063_MERGE_SENSE_GP_FB2 0x00 +#define DA9063_MERGE_SENSE_GPIO4 0x04 +#define DA9063_BCORE_MERGE 0x08 +#define DA9063_BPRO_OD 0x10 +#define DA9063_BCORE2_OD 0x20 +#define DA9063_BCORE1_OD 0x40 +#define DA9063_BUCK_MERGE 0x80 + +/* DA9063_REG_CONFIG_I (addr=0x10E) */ +#define DA9063_NONKEY_PIN_MASK 0x03 +#define DA9063_NONKEY_PIN_PORT 0x00 +#define DA9063_NONKEY_PIN_SWDOWN 0x01 +#define DA9063_NONKEY_PIN_AUTODOWN 0x02 +#define DA9063_NONKEY_PIN_AUTOFLPRT 0x03 + +/* DA9063_REG_MON_REG_5 (addr=0x116) */ +#define DA9063_MON_A8_IDX_MASK 0x07 +#define DA9063_MON_A8_IDX_NONE 0x00 +#define DA9063_MON_A8_IDX_BCORE1 0x01 +#define DA9063_MON_A8_IDX_BCORE2 0x02 +#define DA9063_MON_A8_IDX_BPRO 0x03 +#define DA9063_MON_A8_IDX_LDO3 0x04 +#define DA9063_MON_A8_IDX_LDO4 0x05 +#define DA9063_MON_A8_IDX_LDO11 0x06 +#define DA9063_MON_A9_IDX_MASK 0x70 +#define DA9063_MON_A9_IDX_NONE 0x00 +#define DA9063_MON_A9_IDX_BIO 0x01 +#define DA9063_MON_A9_IDX_BMEM 0x02 +#define DA9063_MON_A9_IDX_BPERI 0x03 +#define DA9063_MON_A9_IDX_LDO1 0x04 +#define DA9063_MON_A9_IDX_LDO2 0x05 +#define DA9063_MON_A9_IDX_LDO5 0x06 + +/* DA9063_REG_MON_REG_6 (addr=0x117) */ +#define DA9063_MON_A10_IDX_MASK 0x07 +#define DA9063_MON_A10_IDX_NONE 0x00 +#define DA9063_MON_A10_IDX_LDO6 0x01 +#define DA9063_MON_A10_IDX_LDO7 0x02 +#define DA9063_MON_A10_IDX_LDO8 0x03 +#define DA9063_MON_A10_IDX_LDO9 0x04 +#define DA9063_MON_A10_IDX_LDO10 0x05 + +#endif /* _DA9063_REG_H */ diff --git a/include/linux/mfd/davinci_voicecodec.h b/include/linux/mfd/davinci_voicecodec.h index 0ab61320ffa8..5166935ce66d 100644 --- a/include/linux/mfd/davinci_voicecodec.h +++ b/include/linux/mfd/davinci_voicecodec.h @@ -26,8 +26,11 @@ #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/mfd/core.h> +#include <linux/platform_data/edma.h> -#include <mach/edma.h> +#include <mach/hardware.h> + +struct regmap; /* * Register values. @@ -112,8 +115,7 @@ struct davinci_vc { /* Memory resources */ void __iomem *base; - resource_size_t pbase; - size_t base_size; + struct regmap *regmap; /* MFD cells */ struct mfd_cell cells[DAVINCI_VC_CELLS]; diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h index 77a46ae2fc17..0bd69446bb05 100644 --- a/include/linux/mfd/db8500-prcmu.h +++ b/include/linux/mfd/db8500-prcmu.h @@ -489,7 +489,7 @@ struct prcmu_auto_pm_config { #ifdef CONFIG_MFD_DB8500_PRCMU -void db8500_prcmu_early_init(void); +void db8500_prcmu_early_init(u32 phy_base, u32 size); int prcmu_set_rc_a2p(enum romcode_write); enum romcode_read prcmu_get_rc_p2a(void); enum ap_pwrst prcmu_get_xp70_current_state(void); @@ -522,12 +522,6 @@ int db8500_prcmu_load_a9wdog(u8 id, u32 val); void db8500_prcmu_system_reset(u16 reset_code); int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll); u8 db8500_prcmu_get_power_state_result(void); -int db8500_prcmu_gic_decouple(void); -int db8500_prcmu_gic_recouple(void); -int db8500_prcmu_copy_gic_settings(void); -bool db8500_prcmu_gic_pending_irq(void); -bool db8500_prcmu_pending_irq(void); -bool db8500_prcmu_is_cpu_in_wfi(int cpu); void db8500_prcmu_enable_wakeups(u32 wakeups); int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state); int db8500_prcmu_request_clock(u8 clock, bool enable); @@ -553,7 +547,7 @@ void db8500_prcmu_write_masked(unsigned int reg, u32 mask, u32 value); #else /* !CONFIG_MFD_DB8500_PRCMU */ -static inline void db8500_prcmu_early_init(void) {} +static inline void db8500_prcmu_early_init(u32 phy_base, u32 size) {} static inline int prcmu_set_rc_a2p(enum romcode_write code) { diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h index 3abcca91eecd..ca0790fba2f5 100644 --- a/include/linux/mfd/dbx500-prcmu.h +++ b/include/linux/mfd/dbx500-prcmu.h @@ -134,6 +134,11 @@ enum prcmu_clock { PRCMU_SIACLK, PRCMU_SVACLK, PRCMU_ACLK, + PRCMU_HVACLK, /* Ux540 only */ + PRCMU_G1CLK, /* Ux540 only */ + PRCMU_SDMMCHCLK, + PRCMU_CAMCLK, + PRCMU_BML8580CLK, PRCMU_NUM_REG_CLOCKS, PRCMU_SYSCLK = PRCMU_NUM_REG_CLOCKS, PRCMU_CDCLK, @@ -148,6 +153,13 @@ enum prcmu_clock { PRCMU_DSI0ESCCLK, PRCMU_DSI1ESCCLK, PRCMU_DSI2ESCCLK, + /* LCD DSI PLL - Ux540 only */ + PRCMU_PLLDSI_LCD, + PRCMU_DSI0CLK_LCD, + PRCMU_DSI1CLK_LCD, + PRCMU_DSI0ESCCLK_LCD, + PRCMU_DSI1ESCCLK_LCD, + PRCMU_DSI2ESCCLK_LCD, }; /** @@ -237,6 +249,8 @@ struct prcmu_pdata bool enable_set_ddr_opp; bool enable_ape_opp_100_voltage; struct ab8500_platform_data *ab_platdata; + int ab_irq; + int irq_base; u32 version_offset; u32 legacy_offset; u32 adt_offset; @@ -276,9 +290,9 @@ struct prcmu_fw_version { #if defined(CONFIG_UX500_SOC_DB8500) -static inline void __init prcmu_early_init(void) +static inline void prcmu_early_init(u32 phy_base, u32 size) { - return db8500_prcmu_early_init(); + return db8500_prcmu_early_init(phy_base, size); } static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk, @@ -293,36 +307,6 @@ static inline u8 prcmu_get_power_state_result(void) return db8500_prcmu_get_power_state_result(); } -static inline int prcmu_gic_decouple(void) -{ - return db8500_prcmu_gic_decouple(); -} - -static inline int prcmu_gic_recouple(void) -{ - return db8500_prcmu_gic_recouple(); -} - -static inline bool prcmu_gic_pending_irq(void) -{ - return db8500_prcmu_gic_pending_irq(); -} - -static inline bool prcmu_is_cpu_in_wfi(int cpu) -{ - return db8500_prcmu_is_cpu_in_wfi(cpu); -} - -static inline int prcmu_copy_gic_settings(void) -{ - return db8500_prcmu_copy_gic_settings(); -} - -static inline bool prcmu_pending_irq(void) -{ - return db8500_prcmu_pending_irq(); -} - static inline int prcmu_set_epod(u16 epod_id, u8 epod_state) { return db8500_prcmu_set_epod(epod_id, epod_state); @@ -500,7 +484,7 @@ static inline int prcmu_config_a9wdog(u8 num, bool sleep_auto_off) } #else -static inline void __init prcmu_early_init(void) {} +static inline void prcmu_early_init(u32 phy_base, u32 size) {} static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll) diff --git a/include/linux/mfd/kempld.h b/include/linux/mfd/kempld.h new file mode 100644 index 000000000000..b911ef3add03 --- /dev/null +++ b/include/linux/mfd/kempld.h @@ -0,0 +1,125 @@ +/* + * Kontron PLD driver definitions + * + * Copyright (c) 2010-2012 Kontron Europe GmbH + * Author: Michael Brunner <michael.brunner@kontron.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 2 as published + * by the Free Software Foundation. + */ + +#ifndef _LINUX_MFD_KEMPLD_H_ +#define _LINUX_MFD_KEMPLD_H_ + +/* kempld register definitions */ +#define KEMPLD_IOINDEX 0xa80 +#define KEMPLD_IODATA 0xa81 +#define KEMPLD_MUTEX_KEY 0x80 +#define KEMPLD_VERSION 0x00 +#define KEMPLD_VERSION_LSB 0x00 +#define KEMPLD_VERSION_MSB 0x01 +#define KEMPLD_VERSION_GET_MINOR(x) (x & 0x1f) +#define KEMPLD_VERSION_GET_MAJOR(x) ((x >> 5) & 0x1f) +#define KEMPLD_VERSION_GET_NUMBER(x) ((x >> 10) & 0xf) +#define KEMPLD_VERSION_GET_TYPE(x) ((x >> 14) & 0x3) +#define KEMPLD_BUILDNR 0x02 +#define KEMPLD_BUILDNR_LSB 0x02 +#define KEMPLD_BUILDNR_MSB 0x03 +#define KEMPLD_FEATURE 0x04 +#define KEMPLD_FEATURE_LSB 0x04 +#define KEMPLD_FEATURE_MSB 0x05 +#define KEMPLD_FEATURE_BIT_I2C (1 << 0) +#define KEMPLD_FEATURE_BIT_WATCHDOG (1 << 1) +#define KEMPLD_FEATURE_BIT_GPIO (1 << 2) +#define KEMPLD_FEATURE_MASK_UART (7 << 3) +#define KEMPLD_FEATURE_BIT_NMI (1 << 8) +#define KEMPLD_FEATURE_BIT_SMI (1 << 9) +#define KEMPLD_FEATURE_BIT_SCI (1 << 10) +#define KEMPLD_SPEC 0x06 +#define KEMPLD_SPEC_GET_MINOR(x) (x & 0x0f) +#define KEMPLD_SPEC_GET_MAJOR(x) ((x >> 4) & 0x0f) +#define KEMPLD_IRQ_GPIO 0x35 +#define KEMPLD_IRQ_I2C 0x36 +#define KEMPLD_CFG 0x37 +#define KEMPLD_CFG_GPIO_I2C_MUX (1 << 0) +#define KEMPLD_CFG_BIOS_WP (1 << 7) + +#define KEMPLD_CLK 33333333 + +#define KEMPLD_TYPE_RELEASE 0x0 +#define KEMPLD_TYPE_DEBUG 0x1 +#define KEMPLD_TYPE_CUSTOM 0x2 + +/** + * struct kempld_info - PLD device information structure + * @major: PLD major revision + * @minor: PLD minor revision + * @buildnr: PLD build number + * @number: PLD board specific index + * @type: PLD type + * @spec_major: PLD FW specification major revision + * @spec_minor: PLD FW specification minor revision + */ +struct kempld_info { + unsigned int major; + unsigned int minor; + unsigned int buildnr; + unsigned int number; + unsigned int type; + unsigned int spec_major; + unsigned int spec_minor; +}; + +/** + * struct kempld_device_data - Internal representation of the PLD device + * @io_base: Pointer to the IO memory + * @io_index: Pointer to the IO index register + * @io_data: Pointer to the IO data register + * @pld_clock: PLD clock frequency + * @feature_mask: PLD feature mask + * @dev: Pointer to kernel device structure + * @info: KEMPLD info structure + * @lock: PLD mutex + */ +struct kempld_device_data { + void __iomem *io_base; + void __iomem *io_index; + void __iomem *io_data; + u32 pld_clock; + u32 feature_mask; + struct device *dev; + struct kempld_info info; + struct mutex lock; +}; + +/** + * struct kempld_platform_data - PLD hardware configuration structure + * @pld_clock: PLD clock frequency + * @gpio_base GPIO base pin number + * @ioresource: IO addresses of the PLD + * @get_mutex: PLD specific get_mutex callback + * @release_mutex: PLD specific release_mutex callback + * @get_info: PLD specific get_info callback + * @register_cells: PLD specific register_cells callback + */ +struct kempld_platform_data { + u32 pld_clock; + int gpio_base; + struct resource *ioresource; + void (*get_hardware_mutex) (struct kempld_device_data *); + void (*release_hardware_mutex) (struct kempld_device_data *); + int (*get_info) (struct kempld_device_data *); + int (*register_cells) (struct kempld_device_data *); +}; + +extern void kempld_get_mutex(struct kempld_device_data *pld); +extern void kempld_release_mutex(struct kempld_device_data *pld); +extern u8 kempld_read8(struct kempld_device_data *pld, u8 index); +extern void kempld_write8(struct kempld_device_data *pld, u8 index, u8 data); +extern u16 kempld_read16(struct kempld_device_data *pld, u8 index); +extern void kempld_write16(struct kempld_device_data *pld, u8 index, u16 data); +extern u32 kempld_read32(struct kempld_device_data *pld, u8 index); +extern void kempld_write32(struct kempld_device_data *pld, u8 index, u32 data); + +#endif /* _LINUX_MFD_KEMPLD_H_ */ diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h index 5b18ecde69b5..244fb0d51589 100644 --- a/include/linux/mfd/max77693-private.h +++ b/include/linux/mfd/max77693-private.h @@ -85,6 +85,19 @@ enum max77693_pmic_reg { MAX77693_PMIC_REG_END, }; +/* MAX77693 CHG_CNFG_00 register */ +#define CHG_CNFG_00_CHG_MASK 0x1 +#define CHG_CNFG_00_BUCK_MASK 0x4 + +/* MAX77693 CHG_CNFG_09 Register */ +#define CHG_CNFG_09_CHGIN_ILIM_MASK 0x7F + +/* MAX77693 CHG_CTRL Register */ +#define SAFEOUT_CTRL_SAFEOUT1_MASK 0x3 +#define SAFEOUT_CTRL_SAFEOUT2_MASK 0xC +#define SAFEOUT_CTRL_ENSAFEOUT1_MASK 0x40 +#define SAFEOUT_CTRL_ENSAFEOUT2_MASK 0x80 + /* Slave addr = 0x4A: MUIC */ enum max77693_muic_reg { MAX77693_MUIC_REG_ID = 0x00, @@ -106,6 +119,29 @@ enum max77693_muic_reg { MAX77693_MUIC_REG_END, }; +/* MAX77693 INTMASK1~2 Register */ +#define INTMASK1_ADC1K_SHIFT 3 +#define INTMASK1_ADCERR_SHIFT 2 +#define INTMASK1_ADCLOW_SHIFT 1 +#define INTMASK1_ADC_SHIFT 0 +#define INTMASK1_ADC1K_MASK (1 << INTMASK1_ADC1K_SHIFT) +#define INTMASK1_ADCERR_MASK (1 << INTMASK1_ADCERR_SHIFT) +#define INTMASK1_ADCLOW_MASK (1 << INTMASK1_ADCLOW_SHIFT) +#define INTMASK1_ADC_MASK (1 << INTMASK1_ADC_SHIFT) + +#define INTMASK2_VIDRM_SHIFT 5 +#define INTMASK2_VBVOLT_SHIFT 4 +#define INTMASK2_DXOVP_SHIFT 3 +#define INTMASK2_DCDTMR_SHIFT 2 +#define INTMASK2_CHGDETRUN_SHIFT 1 +#define INTMASK2_CHGTYP_SHIFT 0 +#define INTMASK2_VIDRM_MASK (1 << INTMASK2_VIDRM_SHIFT) +#define INTMASK2_VBVOLT_MASK (1 << INTMASK2_VBVOLT_SHIFT) +#define INTMASK2_DXOVP_MASK (1 << INTMASK2_DXOVP_SHIFT) +#define INTMASK2_DCDTMR_MASK (1 << INTMASK2_DCDTMR_SHIFT) +#define INTMASK2_CHGDETRUN_MASK (1 << INTMASK2_CHGDETRUN_SHIFT) +#define INTMASK2_CHGTYP_MASK (1 << INTMASK2_CHGTYP_SHIFT) + /* MAX77693 MUIC - STATUS1~3 Register */ #define STATUS1_ADC_SHIFT (0) #define STATUS1_ADCLOW_SHIFT (5) diff --git a/include/linux/mfd/max77693.h b/include/linux/mfd/max77693.h index 3109a6c5c948..676f0f388992 100644 --- a/include/linux/mfd/max77693.h +++ b/include/linux/mfd/max77693.h @@ -30,6 +30,20 @@ #ifndef __LINUX_MFD_MAX77693_H #define __LINUX_MFD_MAX77693_H +/* MAX77686 regulator IDs */ +enum max77693_regulators { + MAX77693_ESAFEOUT1 = 0, + MAX77693_ESAFEOUT2, + MAX77693_CHARGER, + MAX77693_REG_MAX, +}; + +struct max77693_regulator_data { + int id; + struct regulator_init_data *initdata; + struct device_node *of_node; +}; + struct max77693_reg_data { u8 addr; u8 data; @@ -52,6 +66,10 @@ struct max77693_muic_platform_data { struct max77693_platform_data { int wakeup; + /* regulator data */ + struct max77693_regulator_data *regulators; + int num_regulators; + /* muic data */ struct max77693_muic_platform_data *muic_data; }; diff --git a/include/linux/mfd/max8998-private.h b/include/linux/mfd/max8998-private.h index effa5d3b96ae..84844e0a5704 100644 --- a/include/linux/mfd/max8998-private.h +++ b/include/linux/mfd/max8998-private.h @@ -132,9 +132,12 @@ enum { #define MAX8998_ENRAMP (1 << 4) +struct irq_domain; + /** * struct max8998_dev - max8998 master device for sub-drivers * @dev: master device of the chip (can be used to access platform data) + * @pdata: platform data for the driver and subdrivers * @i2c: i2c client private data for regulator * @rtc: i2c client private data for rtc * @iolock: mutex for serializing io access @@ -148,12 +151,14 @@ enum { */ struct max8998_dev { struct device *dev; + struct max8998_platform_data *pdata; struct i2c_client *i2c; struct i2c_client *rtc; struct mutex iolock; struct mutex irqlock; - int irq_base; + unsigned int irq_base; + struct irq_domain *irq_domain; int irq; int ono; u8 irq_masks_cur[MAX8998_NUM_IRQ_REGS]; diff --git a/include/linux/mfd/max8998.h b/include/linux/mfd/max8998.h index 6823548d0c0a..e3956a654cbc 100644 --- a/include/linux/mfd/max8998.h +++ b/include/linux/mfd/max8998.h @@ -58,10 +58,12 @@ enum { * max8998_regulator_data - regulator data * @id: regulator id * @initdata: regulator init data (contraints, supplies, ...) + * @reg_node: DT node of regulator (unused on non-DT platforms) */ struct max8998_regulator_data { int id; struct regulator_init_data *initdata; + struct device_node *reg_node; }; /** @@ -73,12 +75,8 @@ struct max8998_regulator_data { * @buck_voltage_lock: Do NOT change the values of the following six * registers set by buck?_voltage?. The voltage of BUCK1/2 cannot * be other than the preset values. - * @buck1_voltage1: BUCK1 DVS mode 1 voltage register - * @buck1_voltage2: BUCK1 DVS mode 2 voltage register - * @buck1_voltage3: BUCK1 DVS mode 3 voltage register - * @buck1_voltage4: BUCK1 DVS mode 4 voltage register - * @buck2_voltage1: BUCK2 DVS mode 1 voltage register - * @buck2_voltage2: BUCK2 DVS mode 2 voltage register + * @buck1_voltage: BUCK1 DVS mode 1 voltage registers + * @buck2_voltage: BUCK2 DVS mode 2 voltage registers * @buck1_set1: BUCK1 gpio pin 1 to set output voltage * @buck1_set2: BUCK1 gpio pin 2 to set output voltage * @buck1_default_idx: Default for BUCK1 gpio pin 1, 2 @@ -100,15 +98,11 @@ struct max8998_regulator_data { struct max8998_platform_data { struct max8998_regulator_data *regulators; int num_regulators; - int irq_base; + unsigned int irq_base; int ono; bool buck_voltage_lock; - int buck1_voltage1; - int buck1_voltage2; - int buck1_voltage3; - int buck1_voltage4; - int buck2_voltage1; - int buck2_voltage2; + int buck1_voltage[4]; + int buck2_voltage[2]; int buck1_set1; int buck1_set2; int buck1_default_idx; diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h index bf070755982e..67c17b5a6f44 100644 --- a/include/linux/mfd/mc13xxx.h +++ b/include/linux/mfd/mc13xxx.h @@ -41,6 +41,13 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, unsigned int channel, u8 ato, bool atox, unsigned int *sample); +#define MC13783_AUDIO_RX0 36 +#define MC13783_AUDIO_RX1 37 +#define MC13783_AUDIO_TX 38 +#define MC13783_SSI_NETWORK 39 +#define MC13783_AUDIO_CODEC 40 +#define MC13783_AUDIO_DAC 41 + #define MC13XXX_IRQ_ADCDONE 0 #define MC13XXX_IRQ_ADCBISDONE 1 #define MC13XXX_IRQ_TS 2 @@ -78,20 +85,30 @@ struct mc13xxx_regulator_platform_data { struct mc13xxx_regulator_init_data *regulators; }; +enum { + /* MC13783 LED IDs */ + MC13783_LED_MD, + MC13783_LED_AD, + MC13783_LED_KP, + MC13783_LED_R1, + MC13783_LED_G1, + MC13783_LED_B1, + MC13783_LED_R2, + MC13783_LED_G2, + MC13783_LED_B2, + MC13783_LED_R3, + MC13783_LED_G3, + MC13783_LED_B3, + /* MC13892 LED IDs */ + MC13892_LED_MD, + MC13892_LED_AD, + MC13892_LED_KP, + MC13892_LED_R, + MC13892_LED_G, + MC13892_LED_B, +}; + struct mc13xxx_led_platform_data { -#define MC13783_LED_MD 0 -#define MC13783_LED_AD 1 -#define MC13783_LED_KP 2 -#define MC13783_LED_R1 3 -#define MC13783_LED_G1 4 -#define MC13783_LED_B1 5 -#define MC13783_LED_R2 6 -#define MC13783_LED_G2 7 -#define MC13783_LED_B2 8 -#define MC13783_LED_R3 9 -#define MC13783_LED_G3 10 -#define MC13783_LED_B3 11 -#define MC13783_LED_MAX MC13783_LED_B3 int id; const char *name; const char *default_trigger; @@ -100,46 +117,36 @@ struct mc13xxx_led_platform_data { char max_current; }; +#define MAX_LED_CONTROL_REGS 6 + struct mc13xxx_leds_platform_data { - int num_leds; struct mc13xxx_led_platform_data *led; + int num_leds; -#define MC13783_LED_TRIODE_MD (1 << 0) -#define MC13783_LED_TRIODE_AD (1 << 1) -#define MC13783_LED_TRIODE_KP (1 << 2) -#define MC13783_LED_BOOST_EN (1 << 3) -#define MC13783_LED_TC1HALF (1 << 4) -#define MC13783_LED_SLEWLIMTC (1 << 5) -#define MC13783_LED_SLEWLIMBL (1 << 6) -#define MC13783_LED_TRIODE_TC1 (1 << 7) -#define MC13783_LED_TRIODE_TC2 (1 << 8) -#define MC13783_LED_TRIODE_TC3 (1 << 9) - int flags; - -#define MC13783_LED_AB_DISABLED 0 -#define MC13783_LED_AB_MD1 1 -#define MC13783_LED_AB_MD12 2 -#define MC13783_LED_AB_MD123 3 -#define MC13783_LED_AB_MD1234 4 -#define MC13783_LED_AB_MD1234_AD1 5 -#define MC13783_LED_AB_MD1234_AD12 6 -#define MC13783_LED_AB_MD1_AD 7 - char abmode; - -#define MC13783_LED_ABREF_200MV 0 -#define MC13783_LED_ABREF_400MV 1 -#define MC13783_LED_ABREF_600MV 2 -#define MC13783_LED_ABREF_800MV 3 - char abref; - -#define MC13783_LED_PERIOD_10MS 0 -#define MC13783_LED_PERIOD_100MS 1 -#define MC13783_LED_PERIOD_500MS 2 -#define MC13783_LED_PERIOD_2S 3 - char bl_period; - char tc1_period; - char tc2_period; - char tc3_period; +/* LED Control 0 */ +#define MC13783_LED_C0_ENABLE (1 << 0) +#define MC13783_LED_C0_TRIODE_MD (1 << 7) +#define MC13783_LED_C0_TRIODE_AD (1 << 8) +#define MC13783_LED_C0_TRIODE_KP (1 << 9) +#define MC13783_LED_C0_BOOST (1 << 10) +#define MC13783_LED_C0_ABMODE(x) (((x) & 0x7) << 11) +#define MC13783_LED_C0_ABREF(x) (((x) & 0x3) << 14) +/* LED Control 1 */ +#define MC13783_LED_C1_TC1HALF (1 << 18) +#define MC13783_LED_C1_SLEWLIM (1 << 23) +/* LED Control 2 */ +#define MC13783_LED_C2_PERIOD(x) (((x) & 0x3) << 21) +#define MC13783_LED_C2_SLEWLIM (1 << 23) +/* LED Control 3 */ +#define MC13783_LED_C3_PERIOD(x) (((x) & 0x3) << 21) +#define MC13783_LED_C3_TRIODE_TC1 (1 << 23) +/* LED Control 4 */ +#define MC13783_LED_C4_PERIOD(x) (((x) & 0x3) << 21) +#define MC13783_LED_C4_TRIODE_TC2 (1 << 23) +/* LED Control 5 */ +#define MC13783_LED_C5_PERIOD(x) (((x) & 0x3) << 21) +#define MC13783_LED_C5_TRIODE_TC3 (1 << 23) + u32 led_control[MAX_LED_CONTROL_REGS]; }; struct mc13xxx_buttons_platform_data { diff --git a/include/linux/mfd/mcp.h b/include/linux/mfd/mcp.h index a9e8bd157673..f682953043ba 100644 --- a/include/linux/mfd/mcp.h +++ b/include/linux/mfd/mcp.h @@ -10,6 +10,8 @@ #ifndef MCP_H #define MCP_H +#include <linux/device.h> + struct mcp_ops; struct mcp { diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h index a4d13d7cd001..9974e387e483 100644 --- a/include/linux/mfd/palmas.h +++ b/include/linux/mfd/palmas.h @@ -1,9 +1,10 @@ /* * TI Palmas * - * Copyright 2011 Texas Instruments Inc. + * Copyright 2011-2013 Texas Instruments Inc. * * Author: Graeme Gregory <gg@slimlogic.co.uk> + * Author: Ian Lartey <ian@slimlogic.co.uk> * * 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 @@ -19,14 +20,44 @@ #include <linux/leds.h> #include <linux/regmap.h> #include <linux/regulator/driver.h> +#include <linux/extcon.h> +#include <linux/usb/phy_companion.h> #define PALMAS_NUM_CLIENTS 3 +/* The ID_REVISION NUMBERS */ +#define PALMAS_CHIP_OLD_ID 0x0000 +#define PALMAS_CHIP_ID 0xC035 +#define PALMAS_CHIP_CHARGER_ID 0xC036 + +#define is_palmas(a) (((a) == PALMAS_CHIP_OLD_ID) || \ + ((a) == PALMAS_CHIP_ID)) +#define is_palmas_charger(a) ((a) == PALMAS_CHIP_CHARGER_ID) + +/** + * Palmas PMIC feature types + * + * PALMAS_PMIC_FEATURE_SMPS10_BOOST - used when the PMIC provides SMPS10_BOOST + * regulator. + * + * PALMAS_PMIC_HAS(b, f) - macro to check if a bandgap device is capable of a + * specific feature (above) or not. Return non-zero, if yes. + */ +#define PALMAS_PMIC_FEATURE_SMPS10_BOOST BIT(0) +#define PALMAS_PMIC_HAS(b, f) \ + ((b)->features & PALMAS_PMIC_FEATURE_ ## f) + struct palmas_pmic; struct palmas_gpadc; struct palmas_resource; struct palmas_usb; +enum palmas_usb_state { + PALMAS_USB_STATE_DISCONNECT, + PALMAS_USB_STATE_VBUS, + PALMAS_USB_STATE_ID, +}; + struct palmas { struct device *dev; @@ -36,6 +67,7 @@ struct palmas { /* Stored chip id */ int id; + unsigned int features; /* IRQ Data */ int irq; u32 irq_mask; @@ -109,19 +141,6 @@ struct palmas_reg_init { */ int mode_sleep; - /* tstep is the timestep loaded to the TSTEP register - * - * For SMPS - * - * 0: Jump (no slope control) - * 1: 10mV/us - * 2: 5mV/us - * 3: 2.5mV/us - * - * For LDO unused - */ - int tstep; - /* voltage_sel is the bitfield loaded onto the SMPSX_VOLTAGE * register. Set this is the default voltage set in OTP needs * to be overridden. @@ -141,7 +160,8 @@ enum palmas_regulators { PALMAS_REG_SMPS7, PALMAS_REG_SMPS8, PALMAS_REG_SMPS9, - PALMAS_REG_SMPS10, + PALMAS_REG_SMPS10_OUT2, + PALMAS_REG_SMPS10_OUT1, /* LDO regulators */ PALMAS_REG_LDO1, PALMAS_REG_LDO2, @@ -154,10 +174,60 @@ enum palmas_regulators { PALMAS_REG_LDO9, PALMAS_REG_LDOLN, PALMAS_REG_LDOUSB, + /* External regulators */ + PALMAS_REG_REGEN1, + PALMAS_REG_REGEN2, + PALMAS_REG_REGEN3, + PALMAS_REG_SYSEN1, + PALMAS_REG_SYSEN2, /* Total number of regulators */ PALMAS_NUM_REGS, }; +/* External controll signal name */ +enum { + PALMAS_EXT_CONTROL_ENABLE1 = 0x1, + PALMAS_EXT_CONTROL_ENABLE2 = 0x2, + PALMAS_EXT_CONTROL_NSLEEP = 0x4, +}; + +/* + * Palmas device resources can be controlled externally for + * enabling/disabling it rather than register write through i2c. + * Add the external controlled requestor ID for different resources. + */ +enum palmas_external_requestor_id { + PALMAS_EXTERNAL_REQSTR_ID_REGEN1, + PALMAS_EXTERNAL_REQSTR_ID_REGEN2, + PALMAS_EXTERNAL_REQSTR_ID_SYSEN1, + PALMAS_EXTERNAL_REQSTR_ID_SYSEN2, + PALMAS_EXTERNAL_REQSTR_ID_CLK32KG, + PALMAS_EXTERNAL_REQSTR_ID_CLK32KGAUDIO, + PALMAS_EXTERNAL_REQSTR_ID_REGEN3, + PALMAS_EXTERNAL_REQSTR_ID_SMPS12, + PALMAS_EXTERNAL_REQSTR_ID_SMPS3, + PALMAS_EXTERNAL_REQSTR_ID_SMPS45, + PALMAS_EXTERNAL_REQSTR_ID_SMPS6, + PALMAS_EXTERNAL_REQSTR_ID_SMPS7, + PALMAS_EXTERNAL_REQSTR_ID_SMPS8, + PALMAS_EXTERNAL_REQSTR_ID_SMPS9, + PALMAS_EXTERNAL_REQSTR_ID_SMPS10, + PALMAS_EXTERNAL_REQSTR_ID_LDO1, + PALMAS_EXTERNAL_REQSTR_ID_LDO2, + PALMAS_EXTERNAL_REQSTR_ID_LDO3, + PALMAS_EXTERNAL_REQSTR_ID_LDO4, + PALMAS_EXTERNAL_REQSTR_ID_LDO5, + PALMAS_EXTERNAL_REQSTR_ID_LDO6, + PALMAS_EXTERNAL_REQSTR_ID_LDO7, + PALMAS_EXTERNAL_REQSTR_ID_LDO8, + PALMAS_EXTERNAL_REQSTR_ID_LDO9, + PALMAS_EXTERNAL_REQSTR_ID_LDOLN, + PALMAS_EXTERNAL_REQSTR_ID_LDOUSB, + + /* Last entry */ + PALMAS_EXTERNAL_REQSTR_ID_MAX, +}; + struct palmas_pmic_platform_data { /* An array of pointers to regulator init data indexed by regulator * ID @@ -171,12 +241,12 @@ struct palmas_pmic_platform_data { /* use LDO6 for vibrator control */ int ldo6_vibrator; + + /* Enable tracking mode of LDO8 */ + bool enable_ldo8_tracking; }; struct palmas_usb_platform_data { - /* Set this if platform wishes its own vbus control */ - int no_control_vbus; - /* Do we enable the wakeup comparator on probe */ int wakeup; }; @@ -221,6 +291,7 @@ struct palmas_clk_platform_data { }; struct palmas_platform_data { + int irq_flags; int gpio_base; /* bit value to be loaded to the POWER_CTRL register */ @@ -232,6 +303,7 @@ struct palmas_platform_data { */ int mux_from_pdata; u8 pad1, pad2; + bool pm_off; struct palmas_pmic_platform_data *pmic_pdata; struct palmas_gpadc_platform_data *gpadc_pdata; @@ -329,7 +401,9 @@ struct palmas_pmic { int smps123; int smps457; - int range[PALMAS_REG_SMPS10]; + int range[PALMAS_REG_SMPS10_OUT1]; + unsigned int ramp_delay[PALMAS_REG_SMPS10_OUT1]; + unsigned int current_reg_mode[PALMAS_REG_SMPS10_OUT1]; }; struct palmas_resource { @@ -341,22 +415,17 @@ struct palmas_usb { struct palmas *palmas; struct device *dev; - /* for vbus reporting with irqs disabled */ - spinlock_t lock; - - struct regulator *vbus_reg; - - /* used to set vbus, in atomic path */ - struct work_struct set_vbus_work; - - int irq1; - int irq2; - int irq3; - int irq4; + struct extcon_dev edev; - int vbus_enable; + int id_otg_irq; + int id_irq; + int vbus_otg_irq; + int vbus_irq; - u8 linkstat; + enum palmas_usb_state linkstat; + int wakeup; + bool enable_vbus_detection; + bool enable_id_detection; }; #define comparator_to_palmas(x) container_of((x), struct palmas_usb, comparator) @@ -424,7 +493,7 @@ enum usb_irq_events { #define PALMAS_DVFS_BASE 0x180 #define PALMAS_PMU_CONTROL_BASE 0x1A0 #define PALMAS_RESOURCE_BASE 0x1D4 -#define PALMAS_PU_PD_OD_BASE 0x1F4 +#define PALMAS_PU_PD_OD_BASE 0x1F0 #define PALMAS_LED_BASE 0x200 #define PALMAS_INTERRUPT_BASE 0x210 #define PALMAS_USB_OTG_BASE 0x250 @@ -1709,16 +1778,20 @@ enum usb_irq_events { #define PALMAS_REGEN3_CTRL_MODE_ACTIVE_SHIFT 0 /* Registers for function PAD_CONTROL */ -#define PALMAS_PU_PD_INPUT_CTRL1 0x0 -#define PALMAS_PU_PD_INPUT_CTRL2 0x1 -#define PALMAS_PU_PD_INPUT_CTRL3 0x2 -#define PALMAS_OD_OUTPUT_CTRL 0x4 -#define PALMAS_POLARITY_CTRL 0x5 -#define PALMAS_PRIMARY_SECONDARY_PAD1 0x6 -#define PALMAS_PRIMARY_SECONDARY_PAD2 0x7 -#define PALMAS_I2C_SPI 0x8 -#define PALMAS_PU_PD_INPUT_CTRL4 0x9 -#define PALMAS_PRIMARY_SECONDARY_PAD3 0xA +#define PALMAS_OD_OUTPUT_CTRL2 0x2 +#define PALMAS_POLARITY_CTRL2 0x3 +#define PALMAS_PU_PD_INPUT_CTRL1 0x4 +#define PALMAS_PU_PD_INPUT_CTRL2 0x5 +#define PALMAS_PU_PD_INPUT_CTRL3 0x6 +#define PALMAS_PU_PD_INPUT_CTRL5 0x7 +#define PALMAS_OD_OUTPUT_CTRL 0x8 +#define PALMAS_POLARITY_CTRL 0x9 +#define PALMAS_PRIMARY_SECONDARY_PAD1 0xA +#define PALMAS_PRIMARY_SECONDARY_PAD2 0xB +#define PALMAS_I2C_SPI 0xC +#define PALMAS_PU_PD_INPUT_CTRL4 0xD +#define PALMAS_PRIMARY_SECONDARY_PAD3 0xE +#define PALMAS_PRIMARY_SECONDARY_PAD4 0xF /* Bit definitions for PU_PD_INPUT_CTRL1 */ #define PALMAS_PU_PD_INPUT_CTRL1_RESET_IN_PD 0x40 @@ -2476,6 +2549,15 @@ enum usb_irq_events { #define PALMAS_PU_PD_GPIO_CTRL1 0x6 #define PALMAS_PU_PD_GPIO_CTRL2 0x7 #define PALMAS_OD_OUTPUT_GPIO_CTRL 0x8 +#define PALMAS_GPIO_DATA_IN2 0x9 +#define PALMAS_GPIO_DATA_DIR2 0x0A +#define PALMAS_GPIO_DATA_OUT2 0x0B +#define PALMAS_GPIO_DEBOUNCE_EN2 0x0C +#define PALMAS_GPIO_CLEAR_DATA_OUT2 0x0D +#define PALMAS_GPIO_SET_DATA_OUT2 0x0E +#define PALMAS_PU_PD_GPIO_CTRL3 0x0F +#define PALMAS_PU_PD_GPIO_CTRL4 0x10 +#define PALMAS_OD_OUTPUT_GPIO_CTRL2 0x11 /* Bit definitions for GPIO_DATA_IN */ #define PALMAS_GPIO_DATA_IN_GPIO_7_IN 0x80 @@ -2841,4 +2923,9 @@ static inline int palmas_irq_get_virq(struct palmas *palmas, int irq) return regmap_irq_get_virq(palmas->irq_data, irq); } + +int palmas_ext_control_req_config(struct palmas *palmas, + enum palmas_external_requestor_id ext_control_req_id, + int ext_ctrl, bool enable); + #endif /* __LINUX_MFD_PALMAS_H */ diff --git a/include/linux/mfd/retu.h b/include/linux/mfd/retu.h index 1e2715d5b836..65471c4a3926 100644 --- a/include/linux/mfd/retu.h +++ b/include/linux/mfd/retu.h @@ -1,5 +1,5 @@ /* - * Retu MFD driver interface + * Retu/Tahvo MFD driver interface * * This file is subject to the terms and conditions of the GNU General * Public License. See the file "COPYING" in the main directory of this @@ -19,4 +19,10 @@ int retu_write(struct retu_dev *, u8, u16); #define RETU_REG_CC1 0x0d /* Common control register 1 */ #define RETU_REG_STATUS 0x16 /* Status register */ +/* Interrupt sources */ +#define TAHVO_INT_VBUS 0 /* VBUS state */ + +/* Interrupt status */ +#define TAHVO_STAT_VBUS (1 << TAHVO_INT_VBUS) + #endif /* __LINUX_MFD_RETU_H */ diff --git a/include/linux/mfd/rtsx_common.h b/include/linux/mfd/rtsx_common.h index 2b13970596f5..443176ee1ab0 100644 --- a/include/linux/mfd/rtsx_common.h +++ b/include/linux/mfd/rtsx_common.h @@ -1,6 +1,6 @@ /* Driver for Realtek driver-based card reader * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. * * 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 @@ -17,7 +17,6 @@ * * Author: * Wei WANG <wei_wang@realsil.com.cn> - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China */ #ifndef __RTSX_COMMON_H diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h index 26ea7f1b7caf..0ce772105508 100644 --- a/include/linux/mfd/rtsx_pci.h +++ b/include/linux/mfd/rtsx_pci.h @@ -1,6 +1,6 @@ /* Driver for Realtek PCI-Express card reader * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. * * 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 @@ -17,7 +17,6 @@ * * Author: * Wei WANG <wei_wang@realsil.com.cn> - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China */ #ifndef __RTSX_PCI_H @@ -25,8 +24,7 @@ #include <linux/sched.h> #include <linux/pci.h> - -#include "rtsx_common.h" +#include <linux/mfd/rtsx_common.h> #define MAX_RW_REG_CNT 1024 @@ -184,11 +182,26 @@ #define CARD_SHARE_BAROSSA_SD 0x01 #define CARD_SHARE_BAROSSA_MS 0x02 +/* CARD_DRIVE_SEL */ +#define MS_DRIVE_8mA (0x01 << 6) +#define MMC_DRIVE_8mA (0x01 << 4) +#define XD_DRIVE_8mA (0x01 << 2) +#define GPIO_DRIVE_8mA 0x01 +#define RTS5209_CARD_DRIVE_DEFAULT (MS_DRIVE_8mA | MMC_DRIVE_8mA |\ + XD_DRIVE_8mA | GPIO_DRIVE_8mA) +#define RTL8411_CARD_DRIVE_DEFAULT (MS_DRIVE_8mA | MMC_DRIVE_8mA |\ + XD_DRIVE_8mA) +#define RTSX_CARD_DRIVE_DEFAULT (MS_DRIVE_8mA | GPIO_DRIVE_8mA) + /* SD30_DRIVE_SEL */ #define DRIVER_TYPE_A 0x05 #define DRIVER_TYPE_B 0x03 #define DRIVER_TYPE_C 0x02 #define DRIVER_TYPE_D 0x01 +#define CFG_DRIVER_TYPE_A 0x02 +#define CFG_DRIVER_TYPE_B 0x03 +#define CFG_DRIVER_TYPE_C 0x01 +#define CFG_DRIVER_TYPE_D 0x00 /* FPDCTL */ #define SSC_POWER_DOWN 0x01 @@ -500,6 +513,8 @@ #define BPP_POWER_15_PERCENT_ON 0x08 #define BPP_POWER_ON 0x00 #define BPP_POWER_MASK 0x0F +#define SD_VCC_PARTIAL_POWER_ON 0x02 +#define SD_VCC_POWER_ON 0x00 /* PWR_GATE_CTRL */ #define PWR_GATE_EN 0x01 @@ -519,6 +534,10 @@ #define SAMPLE_VAR_CLK0 (0x01 << 4) #define SAMPLE_VAR_CLK1 (0x02 << 4) +/* HOST_SLEEP_STATE */ +#define HOST_ENTER_S1 1 +#define HOST_ENTER_S3 2 + #define MS_CFG 0xFD40 #define MS_TPC 0xFD41 #define MS_TRANS_CFG 0xFD42 @@ -573,6 +592,7 @@ #define CARD_PWR_CTL 0xFD50 #define CARD_CLK_SWITCH 0xFD51 +#define RTL8411B_PACKAGE_MODE 0xFD51 #define CARD_SHARE_MODE 0xFD52 #define CARD_DRIVE_SEL 0xFD53 #define CARD_STOP 0xFD54 @@ -666,6 +686,7 @@ #define PME_FORCE_CTL 0xFE56 #define ASPM_FORCE_CTL 0xFE57 #define PM_CLK_FORCE_CTL 0xFE58 +#define FUNC_FORCE_CTL 0xFE59 #define PERST_GLITCH_WIDTH 0xFE5C #define CHANGE_LINK_STATE 0xFE5B #define RESET_LOAD_REG 0xFE5E @@ -681,6 +702,13 @@ #define DUMMY_REG_RESET_0 0xFE90 +#define AUTOLOAD_CFG_BASE 0xFF00 + +#define PM_CTRL1 0xFF44 +#define PM_CTRL2 0xFF45 +#define PM_CTRL3 0xFF46 +#define PM_CTRL4 0xFF47 + /* Memory mapping */ #define SRAM_BASE 0xE600 #define RBUF_BASE 0xF400 @@ -689,6 +717,98 @@ #define IMAGE_FLAG_ADDR0 0xCE80 #define IMAGE_FLAG_ADDR1 0xCE81 +/* Phy register */ +#define PHY_PCR 0x00 +#define PHY_RCR0 0x01 +#define PHY_RCR1 0x02 +#define PHY_RCR2 0x03 +#define PHY_RTCR 0x04 +#define PHY_RDR 0x05 +#define PHY_TCR0 0x06 +#define PHY_TCR1 0x07 +#define PHY_TUNE 0x08 +#define PHY_IMR 0x09 +#define PHY_BPCR 0x0A +#define PHY_BIST 0x0B +#define PHY_RAW_L 0x0C +#define PHY_RAW_H 0x0D +#define PHY_RAW_DATA 0x0E +#define PHY_HOST_CLK_CTRL 0x0F +#define PHY_DMR 0x10 +#define PHY_BACR 0x11 +#define PHY_IER 0x12 +#define PHY_BCSR 0x13 +#define PHY_BPR 0x14 +#define PHY_BPNR2 0x15 +#define PHY_BPNR 0x16 +#define PHY_BRNR2 0x17 +#define PHY_BENR 0x18 +#define PHY_REG_REV 0x19 +#define PHY_FLD0 0x1A +#define PHY_FLD1 0x1B +#define PHY_FLD2 0x1C +#define PHY_FLD3 0x1D +#define PHY_FLD4 0x1E +#define PHY_DUM_REG 0x1F + +#define LCTLR 0x80 +#define PCR_SETTING_REG1 0x724 +#define PCR_SETTING_REG2 0x814 +#define PCR_SETTING_REG3 0x747 + +/* Phy bits */ +#define PHY_PCR_FORCE_CODE 0xB000 +#define PHY_PCR_OOBS_CALI_50 0x0800 +#define PHY_PCR_OOBS_VCM_08 0x0200 +#define PHY_PCR_OOBS_SEN_90 0x0040 +#define PHY_PCR_RSSI_EN 0x0002 + +#define PHY_RCR1_ADP_TIME 0x0100 +#define PHY_RCR1_VCO_COARSE 0x001F + +#define PHY_RCR2_EMPHASE_EN 0x8000 +#define PHY_RCR2_NADJR 0x4000 +#define PHY_RCR2_CDR_CP_10 0x0400 +#define PHY_RCR2_CDR_SR_2 0x0100 +#define PHY_RCR2_FREQSEL_12 0x0040 +#define PHY_RCR2_CPADJEN 0x0020 +#define PHY_RCR2_CDR_SC_8 0x0008 +#define PHY_RCR2_CALIB_LATE 0x0002 + +#define PHY_RDR_RXDSEL_1_9 0x4000 + +#define PHY_TUNE_TUNEREF_1_0 0x4000 +#define PHY_TUNE_VBGSEL_1252 0x0C00 +#define PHY_TUNE_SDBUS_33 0x0200 +#define PHY_TUNE_TUNED18 0x01C0 +#define PHY_TUNE_TUNED12 0X0020 + +#define PHY_BPCR_IBRXSEL 0x0400 +#define PHY_BPCR_IBTXSEL 0x0100 +#define PHY_BPCR_IB_FILTER 0x0080 +#define PHY_BPCR_CMIRROR_EN 0x0040 + +#define PHY_REG_REV_RESV 0xE000 +#define PHY_REG_REV_RXIDLE_LATCHED 0x1000 +#define PHY_REG_REV_P1_EN 0x0800 +#define PHY_REG_REV_RXIDLE_EN 0x0400 +#define PHY_REG_REV_CLKREQ_DLY_TIMER_1_0 0x0040 +#define PHY_REG_REV_STOP_CLKRD 0x0020 +#define PHY_REG_REV_RX_PWST 0x0008 +#define PHY_REG_REV_STOP_CLKWR 0x0004 + +#define PHY_FLD3_TIMER_4 0x7800 +#define PHY_FLD3_TIMER_6 0x00E0 +#define PHY_FLD3_RXDELINK 0x0004 + +#define PHY_FLD4_FLDEN_SEL 0x4000 +#define PHY_FLD4_REQ_REF 0x2000 +#define PHY_FLD4_RXAMP_OFF 0x1000 +#define PHY_FLD4_REQ_ADDA 0x0800 +#define PHY_FLD4_BER_COUNT 0x00E0 +#define PHY_FLD4_BER_TIMER 0x000A +#define PHY_FLD4_BER_CHK_EN 0x0001 + #define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0) struct rtsx_pcr; @@ -710,6 +830,8 @@ struct pcr_ops { u8 voltage); unsigned int (*cd_deglitch)(struct rtsx_pcr *pcr); int (*conv_clk_and_div_n)(int clk, int dir); + void (*fetch_vendor_settings)(struct rtsx_pcr *pcr); + void (*force_power_down)(struct rtsx_pcr *pcr, u8 pm_state); }; enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN}; @@ -751,7 +873,6 @@ struct rtsx_pcr { struct completion *finish_me; unsigned int cur_clock; - bool ms_pmos; bool remove_pci; bool msi_en; @@ -769,6 +890,19 @@ struct rtsx_pcr { #define IC_VER_D 3 u8 ic_version; + u8 sd30_drive_sel_1v8; + u8 sd30_drive_sel_3v3; + u8 card_drive_sel; +#define ASPM_L1_EN 0x02 + u8 aspm_en; + +#define PCR_MS_PMOS (1 << 0) +#define PCR_REVERSE_SOCKET (1 << 1) + u32 flags; + + u32 tx_initial_phase; + u32 rx_initial_phase; + const u32 *sd_pull_ctl_enable_tbl; const u32 *sd_pull_ctl_disable_tbl; const u32 *ms_pull_ctl_enable_tbl; @@ -785,6 +919,18 @@ struct rtsx_pcr { #define PCI_VID(pcr) ((pcr)->pci->vendor) #define PCI_PID(pcr) ((pcr)->pci->device) +#define SDR104_PHASE(val) ((val) & 0xFF) +#define SDR50_PHASE(val) (((val) >> 8) & 0xFF) +#define DDR50_PHASE(val) (((val) >> 16) & 0xFF) +#define SDR104_TX_PHASE(pcr) SDR104_PHASE((pcr)->tx_initial_phase) +#define SDR50_TX_PHASE(pcr) SDR50_PHASE((pcr)->tx_initial_phase) +#define DDR50_TX_PHASE(pcr) DDR50_PHASE((pcr)->tx_initial_phase) +#define SDR104_RX_PHASE(pcr) SDR104_PHASE((pcr)->rx_initial_phase) +#define SDR50_RX_PHASE(pcr) SDR50_PHASE((pcr)->rx_initial_phase) +#define DDR50_RX_PHASE(pcr) DDR50_PHASE((pcr)->rx_initial_phase) +#define SET_CLOCK_PHASE(sdr104, sdr50, ddr50) \ + (((ddr50) << 16) | ((sdr50) << 8) | (sdr104)) + void rtsx_pci_start_run(struct rtsx_pcr *pcr); int rtsx_pci_write_register(struct rtsx_pcr *pcr, u16 addr, u8 mask, u8 data); int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, u8 *data); diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index f0f4de3b4ccc..378ae8a04c6a 100644 --- a/include/linux/mfd/samsung/core.h +++ b/include/linux/mfd/samsung/core.h @@ -14,8 +14,6 @@ #ifndef __LINUX_MFD_SEC_CORE_H #define __LINUX_MFD_SEC_CORE_H -#define NUM_IRQ_REGS 4 - enum sec_device_type { S5M8751X, S5M8763X, @@ -44,8 +42,6 @@ struct sec_pmic_dev { struct regmap *regmap; struct i2c_client *i2c; struct i2c_client *rtc; - struct mutex iolock; - struct mutex irqlock; int device_type; int irq_base; @@ -53,8 +49,6 @@ struct sec_pmic_dev { struct regmap_irq_chip_data *irq_data; int ono; - u8 irq_masks_cur[NUM_IRQ_REGS]; - u8 irq_masks_cache[NUM_IRQ_REGS]; int type; bool wakeup; }; diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h index ad2252f239d7..b3ddf98dec37 100644 --- a/include/linux/mfd/samsung/s2mps11.h +++ b/include/linux/mfd/samsung/s2mps11.h @@ -167,11 +167,8 @@ enum s2mps11_regulators { S2MPS11_BUCK8, S2MPS11_BUCK9, S2MPS11_BUCK10, - S2MPS11_AP_EN32KHZ, - S2MPS11_CP_EN32KHZ, - S2MPS11_BT_EN32KHZ, - S2MPS11_REG_MAX, + S2MPS11_REGULATOR_MAX, }; #define S2MPS11_BUCK_MIN1 600000 @@ -189,8 +186,19 @@ enum s2mps11_regulators { #define S2MPS11_ENABLE_SHIFT 0x06 #define S2MPS11_LDO_N_VOLTAGES (S2MPS11_LDO_VSEL_MASK + 1) #define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1) +#define S2MPS11_RAMP_DELAY 25000 /* uV/us */ + +#define S2MPS11_BUCK2_RAMP_SHIFT 6 +#define S2MPS11_BUCK34_RAMP_SHIFT 4 +#define S2MPS11_BUCK5_RAMP_SHIFT 6 +#define S2MPS11_BUCK16_RAMP_SHIFT 4 +#define S2MPS11_BUCK7810_RAMP_SHIFT 2 +#define S2MPS11_BUCK9_RAMP_SHIFT 0 +#define S2MPS11_BUCK2_RAMP_EN_SHIFT 3 +#define S2MPS11_BUCK3_RAMP_EN_SHIFT 2 +#define S2MPS11_BUCK4_RAMP_EN_SHIFT 1 +#define S2MPS11_BUCK6_RAMP_EN_SHIFT 0 #define S2MPS11_PMIC_EN_SHIFT 6 -#define S2MPS11_REGULATOR_MAX (S2MPS11_REG_MAX - 3) #endif /* __LINUX_MFD_S2MPS11_H */ diff --git a/include/linux/mfd/si476x-core.h b/include/linux/mfd/si476x-core.h new file mode 100644 index 000000000000..ba89b94e4a56 --- /dev/null +++ b/include/linux/mfd/si476x-core.h @@ -0,0 +1,533 @@ +/* + * include/media/si476x-core.h -- Common definitions for si476x core + * device + * + * Copyright (C) 2012 Innovative Converged Devices(ICD) + * Copyright (C) 2013 Andrey Smirnov + * + * Author: Andrey Smirnov <andrew.smirnov@gmail.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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#ifndef SI476X_CORE_H +#define SI476X_CORE_H + +#include <linux/kfifo.h> +#include <linux/atomic.h> +#include <linux/i2c.h> +#include <linux/regmap.h> +#include <linux/mutex.h> +#include <linux/mfd/core.h> +#include <linux/videodev2.h> +#include <linux/regulator/consumer.h> + +#include <linux/mfd/si476x-platform.h> +#include <linux/mfd/si476x-reports.h> + +/* Command Timeouts */ +#define SI476X_DEFAULT_TIMEOUT 100000 +#define SI476X_TIMEOUT_TUNE 700000 +#define SI476X_TIMEOUT_POWER_UP 330000 +#define SI476X_STATUS_POLL_US 0 + +/* -------------------- si476x-i2c.c ----------------------- */ + +enum si476x_freq_supported_chips { + SI476X_CHIP_SI4761 = 1, + SI476X_CHIP_SI4764, + SI476X_CHIP_SI4768, +}; + +enum si476x_part_revisions { + SI476X_REVISION_A10 = 0, + SI476X_REVISION_A20 = 1, + SI476X_REVISION_A30 = 2, +}; + +enum si476x_mfd_cells { + SI476X_RADIO_CELL = 0, + SI476X_CODEC_CELL, + SI476X_MFD_CELLS, +}; + +/** + * enum si476x_power_state - possible power state of the si476x + * device. + * + * @SI476X_POWER_DOWN: In this state all regulators are turned off + * and the reset line is pulled low. The device is completely + * inactive. + * @SI476X_POWER_UP_FULL: In this state all the power regualtors are + * turned on, reset line pulled high, IRQ line is enabled(polling is + * active for polling use scenario) and device is turned on with + * POWER_UP command. The device is ready to be used. + * @SI476X_POWER_INCONSISTENT: This state indicates that previous + * power down was inconsistent, meaning some of the regulators were + * not turned down and thus use of the device, without power-cycling + * is impossible. + */ +enum si476x_power_state { + SI476X_POWER_DOWN = 0, + SI476X_POWER_UP_FULL = 1, + SI476X_POWER_INCONSISTENT = 2, +}; + +/** + * struct si476x_core - internal data structure representing the + * underlying "core" device which all the MFD cell-devices use. + * + * @client: Actual I2C client used to transfer commands to the chip. + * @chip_id: Last digit of the chip model(E.g. "1" for SI4761) + * @cells: MFD cell devices created by this driver. + * @cmd_lock: Mutex used to serialize all the requests to the core + * device. This filed should not be used directly. Instead + * si476x_core_lock()/si476x_core_unlock() should be used to get + * exclusive access to the "core" device. + * @users: Active users counter(Used by the radio cell) + * @rds_read_queue: Wait queue used to wait for RDS data. + * @rds_fifo: FIFO in which all the RDS data received from the chip is + * placed. + * @rds_fifo_drainer: Worker that drains on-chip RDS FIFO. + * @rds_drainer_is_working: Flag used for launching only one instance + * of the @rds_fifo_drainer. + * @rds_drainer_status_lock: Lock used to guard access to the + * @rds_drainer_is_working variable. + * @command: Wait queue for wainting on the command comapletion. + * @cts: Clear To Send flag set upon receiving first status with CTS + * set. + * @tuning: Wait queue used for wainting for tune/seek comand + * completion. + * @stc: Similar to @cts, but for the STC bit of the status value. + * @power_up_parameters: Parameters used as argument for POWER_UP + * command when the device is started. + * @state: Current power state of the device. + * @supplues: Structure containing handles to all power supplies used + * by the device (NULL ones are ignored). + * @gpio_reset: GPIO pin connectet to the RSTB pin of the chip. + * @pinmux: Chip's configurable pins configuration. + * @diversity_mode: Chips role when functioning in diversity mode. + * @status_monitor: Polling worker used in polling use case scenarion + * (when IRQ is not avalible). + * @revision: Chip's running firmware revision number(Used for correct + * command set support). + */ + +struct si476x_core { + struct i2c_client *client; + struct regmap *regmap; + int chip_id; + struct mfd_cell cells[SI476X_MFD_CELLS]; + + struct mutex cmd_lock; /* for serializing fm radio operations */ + atomic_t users; + + wait_queue_head_t rds_read_queue; + struct kfifo rds_fifo; + struct work_struct rds_fifo_drainer; + bool rds_drainer_is_working; + struct mutex rds_drainer_status_lock; + + wait_queue_head_t command; + atomic_t cts; + + wait_queue_head_t tuning; + atomic_t stc; + + struct si476x_power_up_args power_up_parameters; + + enum si476x_power_state power_state; + + struct regulator_bulk_data supplies[4]; + + int gpio_reset; + + struct si476x_pinmux pinmux; + enum si476x_phase_diversity_mode diversity_mode; + + atomic_t is_alive; + + struct delayed_work status_monitor; +#define SI476X_WORK_TO_CORE(w) container_of(to_delayed_work(w), \ + struct si476x_core, \ + status_monitor) + + int revision; + + int rds_fifo_depth; +}; + +static inline struct si476x_core *i2c_mfd_cell_to_core(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev->parent); + return i2c_get_clientdata(client); +} + + +/** + * si476x_core_lock() - lock the core device to get an exclusive access + * to it. + */ +static inline void si476x_core_lock(struct si476x_core *core) +{ + mutex_lock(&core->cmd_lock); +} + +/** + * si476x_core_unlock() - unlock the core device to relinquish an + * exclusive access to it. + */ +static inline void si476x_core_unlock(struct si476x_core *core) +{ + mutex_unlock(&core->cmd_lock); +} + +/* *_TUNE_FREQ family of commands accept frequency in multiples of + 10kHz */ +static inline u16 hz_to_si476x(struct si476x_core *core, int freq) +{ + u16 result; + + switch (core->power_up_parameters.func) { + default: + case SI476X_FUNC_FM_RECEIVER: + result = freq / 10000; + break; + case SI476X_FUNC_AM_RECEIVER: + result = freq / 1000; + break; + } + + return result; +} + +static inline int si476x_to_hz(struct si476x_core *core, u16 freq) +{ + int result; + + switch (core->power_up_parameters.func) { + default: + case SI476X_FUNC_FM_RECEIVER: + result = freq * 10000; + break; + case SI476X_FUNC_AM_RECEIVER: + result = freq * 1000; + break; + } + + return result; +} + +/* Since the V4L2_TUNER_CAP_LOW flag is supplied, V4L2 subsystem + * mesures frequency in 62.5 Hz units */ + +static inline int hz_to_v4l2(int freq) +{ + return (freq * 10) / 625; +} + +static inline int v4l2_to_hz(int freq) +{ + return (freq * 625) / 10; +} + +static inline u16 v4l2_to_si476x(struct si476x_core *core, int freq) +{ + return hz_to_si476x(core, v4l2_to_hz(freq)); +} + +static inline int si476x_to_v4l2(struct si476x_core *core, u16 freq) +{ + return hz_to_v4l2(si476x_to_hz(core, freq)); +} + + + +/** + * struct si476x_func_info - structure containing result of the + * FUNC_INFO command. + * + * @firmware.major: Firmware major number. + * @firmware.minor[...]: Firmware minor numbers. + * @patch_id: + * @func: Mode tuner is working in. + */ +struct si476x_func_info { + struct { + u8 major, minor[2]; + } firmware; + u16 patch_id; + enum si476x_func func; +}; + +/** + * struct si476x_power_down_args - structure used to pass parameters + * to POWER_DOWN command + * + * @xosc: true - Power down, but leav oscillator running. + * false - Full power down. + */ +struct si476x_power_down_args { + bool xosc; +}; + +/** + * enum si476x_tunemode - enum representing possible tune modes for + * the chip. + * @SI476X_TM_VALIDATED_NORMAL_TUNE: Unconditionally stay on the new + * channel after tune, tune status is valid. + * @SI476X_TM_INVALIDATED_FAST_TUNE: Unconditionally stay in the new + * channel after tune, tune status invalid. + * @SI476X_TM_VALIDATED_AF_TUNE: Jump back to previous channel if + * metric thresholds are not met. + * @SI476X_TM_VALIDATED_AF_CHECK: Unconditionally jump back to the + * previous channel. + */ +enum si476x_tunemode { + SI476X_TM_VALIDATED_NORMAL_TUNE = 0, + SI476X_TM_INVALIDATED_FAST_TUNE = 1, + SI476X_TM_VALIDATED_AF_TUNE = 2, + SI476X_TM_VALIDATED_AF_CHECK = 3, +}; + +/** + * enum si476x_smoothmetrics - enum containing the possible setting fo + * audio transitioning of the chip + * @SI476X_SM_INITIALIZE_AUDIO: Initialize audio state to match this + * new channel + * @SI476X_SM_TRANSITION_AUDIO: Transition audio state from previous + * channel values to the new values + */ +enum si476x_smoothmetrics { + SI476X_SM_INITIALIZE_AUDIO = 0, + SI476X_SM_TRANSITION_AUDIO = 1, +}; + +/** + * struct si476x_rds_status_report - the structure representing the + * response to 'FM_RD_STATUS' command + * @rdstpptyint: Traffic program flag(TP) and/or program type(PTY) + * code has changed. + * @rdspiint: Program indentifiaction(PI) code has changed. + * @rdssyncint: RDS synchronization has changed. + * @rdsfifoint: RDS was received and the RDS FIFO has at least + * 'FM_RDS_INTERRUPT_FIFO_COUNT' elements in it. + * @tpptyvalid: TP flag and PTY code are valid falg. + * @pivalid: PI code is valid flag. + * @rdssync: RDS is currently synchronized. + * @rdsfifolost: On or more RDS groups have been lost/discarded flag. + * @tp: Current channel's TP flag. + * @pty: Current channel's PTY code. + * @pi: Current channel's PI code. + * @rdsfifoused: Number of blocks remaining in the RDS FIFO (0 if + * empty). + */ +struct si476x_rds_status_report { + bool rdstpptyint, rdspiint, rdssyncint, rdsfifoint; + bool tpptyvalid, pivalid, rdssync, rdsfifolost; + bool tp; + + u8 pty; + u16 pi; + + u8 rdsfifoused; + u8 ble[4]; + + struct v4l2_rds_data rds[4]; +}; + +struct si476x_rsq_status_args { + bool primary; + bool rsqack; + bool attune; + bool cancel; + bool stcack; +}; + +enum si476x_injside { + SI476X_INJSIDE_AUTO = 0, + SI476X_INJSIDE_LOW = 1, + SI476X_INJSIDE_HIGH = 2, +}; + +struct si476x_tune_freq_args { + bool zifsr; + bool hd; + enum si476x_injside injside; + int freq; + enum si476x_tunemode tunemode; + enum si476x_smoothmetrics smoothmetrics; + int antcap; +}; + +int si476x_core_stop(struct si476x_core *, bool); +int si476x_core_start(struct si476x_core *, bool); +int si476x_core_set_power_state(struct si476x_core *, enum si476x_power_state); +bool si476x_core_has_am(struct si476x_core *); +bool si476x_core_has_diversity(struct si476x_core *); +bool si476x_core_is_a_secondary_tuner(struct si476x_core *); +bool si476x_core_is_a_primary_tuner(struct si476x_core *); +bool si476x_core_is_in_am_receiver_mode(struct si476x_core *core); +bool si476x_core_is_powered_up(struct si476x_core *core); + +enum si476x_i2c_type { + SI476X_I2C_SEND, + SI476X_I2C_RECV +}; + +int si476x_core_i2c_xfer(struct si476x_core *, + enum si476x_i2c_type, + char *, int); + + +/* -------------------- si476x-cmd.c ----------------------- */ + +int si476x_core_cmd_func_info(struct si476x_core *, struct si476x_func_info *); +int si476x_core_cmd_set_property(struct si476x_core *, u16, u16); +int si476x_core_cmd_get_property(struct si476x_core *, u16); +int si476x_core_cmd_dig_audio_pin_cfg(struct si476x_core *, + enum si476x_dclk_config, + enum si476x_dfs_config, + enum si476x_dout_config, + enum si476x_xout_config); +int si476x_core_cmd_zif_pin_cfg(struct si476x_core *, + enum si476x_iqclk_config, + enum si476x_iqfs_config, + enum si476x_iout_config, + enum si476x_qout_config); +int si476x_core_cmd_ic_link_gpo_ctl_pin_cfg(struct si476x_core *, + enum si476x_icin_config, + enum si476x_icip_config, + enum si476x_icon_config, + enum si476x_icop_config); +int si476x_core_cmd_ana_audio_pin_cfg(struct si476x_core *, + enum si476x_lrout_config); +int si476x_core_cmd_intb_pin_cfg(struct si476x_core *, enum si476x_intb_config, + enum si476x_a1_config); +int si476x_core_cmd_fm_seek_start(struct si476x_core *, bool, bool); +int si476x_core_cmd_am_seek_start(struct si476x_core *, bool, bool); +int si476x_core_cmd_fm_rds_status(struct si476x_core *, bool, bool, bool, + struct si476x_rds_status_report *); +int si476x_core_cmd_fm_rds_blockcount(struct si476x_core *, bool, + struct si476x_rds_blockcount_report *); +int si476x_core_cmd_fm_tune_freq(struct si476x_core *, + struct si476x_tune_freq_args *); +int si476x_core_cmd_am_tune_freq(struct si476x_core *, + struct si476x_tune_freq_args *); +int si476x_core_cmd_am_rsq_status(struct si476x_core *, + struct si476x_rsq_status_args *, + struct si476x_rsq_status_report *); +int si476x_core_cmd_fm_rsq_status(struct si476x_core *, + struct si476x_rsq_status_args *, + struct si476x_rsq_status_report *); +int si476x_core_cmd_power_up(struct si476x_core *, + struct si476x_power_up_args *); +int si476x_core_cmd_power_down(struct si476x_core *, + struct si476x_power_down_args *); +int si476x_core_cmd_fm_phase_div_status(struct si476x_core *); +int si476x_core_cmd_fm_phase_diversity(struct si476x_core *, + enum si476x_phase_diversity_mode); + +int si476x_core_cmd_fm_acf_status(struct si476x_core *, + struct si476x_acf_status_report *); +int si476x_core_cmd_am_acf_status(struct si476x_core *, + struct si476x_acf_status_report *); +int si476x_core_cmd_agc_status(struct si476x_core *, + struct si476x_agc_status_report *); + +enum si476x_power_grid_type { + SI476X_POWER_GRID_50HZ = 0, + SI476X_POWER_GRID_60HZ, +}; + +/* Properties */ + +enum si476x_interrupt_flags { + SI476X_STCIEN = (1 << 0), + SI476X_ACFIEN = (1 << 1), + SI476X_RDSIEN = (1 << 2), + SI476X_RSQIEN = (1 << 3), + + SI476X_ERRIEN = (1 << 6), + SI476X_CTSIEN = (1 << 7), + + SI476X_STCREP = (1 << 8), + SI476X_ACFREP = (1 << 9), + SI476X_RDSREP = (1 << 10), + SI476X_RSQREP = (1 << 11), +}; + +enum si476x_rdsint_sources { + SI476X_RDSTPPTY = (1 << 4), + SI476X_RDSPI = (1 << 3), + SI476X_RDSSYNC = (1 << 1), + SI476X_RDSRECV = (1 << 0), +}; + +enum si476x_status_response_bits { + SI476X_CTS = (1 << 7), + SI476X_ERR = (1 << 6), + /* Status response for WB receiver */ + SI476X_WB_ASQ_INT = (1 << 4), + SI476X_RSQ_INT = (1 << 3), + /* Status response for FM receiver */ + SI476X_FM_RDS_INT = (1 << 2), + SI476X_ACF_INT = (1 << 1), + SI476X_STC_INT = (1 << 0), +}; + +/* -------------------- si476x-prop.c ----------------------- */ + +enum si476x_common_receiver_properties { + SI476X_PROP_INT_CTL_ENABLE = 0x0000, + SI476X_PROP_DIGITAL_IO_INPUT_SAMPLE_RATE = 0x0200, + SI476X_PROP_DIGITAL_IO_INPUT_FORMAT = 0x0201, + SI476X_PROP_DIGITAL_IO_OUTPUT_SAMPLE_RATE = 0x0202, + SI476X_PROP_DIGITAL_IO_OUTPUT_FORMAT = 0x0203, + + SI476X_PROP_SEEK_BAND_BOTTOM = 0x1100, + SI476X_PROP_SEEK_BAND_TOP = 0x1101, + SI476X_PROP_SEEK_FREQUENCY_SPACING = 0x1102, + + SI476X_PROP_VALID_MAX_TUNE_ERROR = 0x2000, + SI476X_PROP_VALID_SNR_THRESHOLD = 0x2003, + SI476X_PROP_VALID_RSSI_THRESHOLD = 0x2004, +}; + +enum si476x_am_receiver_properties { + SI476X_PROP_AUDIO_PWR_LINE_FILTER = 0x0303, +}; + +enum si476x_fm_receiver_properties { + SI476X_PROP_AUDIO_DEEMPHASIS = 0x0302, + + SI476X_PROP_FM_RDS_INTERRUPT_SOURCE = 0x4000, + SI476X_PROP_FM_RDS_INTERRUPT_FIFO_COUNT = 0x4001, + SI476X_PROP_FM_RDS_CONFIG = 0x4002, +}; + +enum si476x_prop_audio_pwr_line_filter_bits { + SI476X_PROP_PWR_HARMONICS_MASK = 0x001f, + SI476X_PROP_PWR_GRID_MASK = 0x0100, + SI476X_PROP_PWR_ENABLE_MASK = 0x0200, + SI476X_PROP_PWR_GRID_50HZ = 0x0000, + SI476X_PROP_PWR_GRID_60HZ = 0x0100, +}; + +enum si476x_prop_fm_rds_config_bits { + SI476X_PROP_RDSEN_MASK = 0x1, + SI476X_PROP_RDSEN = 0x1, +}; + + +struct regmap *devm_regmap_init_si476x(struct si476x_core *); + +#endif /* SI476X_CORE_H */ diff --git a/include/linux/mfd/si476x-platform.h b/include/linux/mfd/si476x-platform.h new file mode 100644 index 000000000000..88bb93b7a9d5 --- /dev/null +++ b/include/linux/mfd/si476x-platform.h @@ -0,0 +1,267 @@ +/* + * include/media/si476x-platform.h -- Platform data specific definitions + * + * Copyright (C) 2013 Andrey Smirnov + * + * Author: Andrey Smirnov <andrew.smirnov@gmail.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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#ifndef __SI476X_PLATFORM_H__ +#define __SI476X_PLATFORM_H__ + +/* It is possible to select one of the four adresses using pins A0 + * and A1 on SI476x */ +#define SI476X_I2C_ADDR_1 0x60 +#define SI476X_I2C_ADDR_2 0x61 +#define SI476X_I2C_ADDR_3 0x62 +#define SI476X_I2C_ADDR_4 0x63 + +enum si476x_iqclk_config { + SI476X_IQCLK_NOOP = 0, + SI476X_IQCLK_TRISTATE = 1, + SI476X_IQCLK_IQ = 21, +}; +enum si476x_iqfs_config { + SI476X_IQFS_NOOP = 0, + SI476X_IQFS_TRISTATE = 1, + SI476X_IQFS_IQ = 21, +}; +enum si476x_iout_config { + SI476X_IOUT_NOOP = 0, + SI476X_IOUT_TRISTATE = 1, + SI476X_IOUT_OUTPUT = 22, +}; +enum si476x_qout_config { + SI476X_QOUT_NOOP = 0, + SI476X_QOUT_TRISTATE = 1, + SI476X_QOUT_OUTPUT = 22, +}; + +enum si476x_dclk_config { + SI476X_DCLK_NOOP = 0, + SI476X_DCLK_TRISTATE = 1, + SI476X_DCLK_DAUDIO = 10, +}; + +enum si476x_dfs_config { + SI476X_DFS_NOOP = 0, + SI476X_DFS_TRISTATE = 1, + SI476X_DFS_DAUDIO = 10, +}; + +enum si476x_dout_config { + SI476X_DOUT_NOOP = 0, + SI476X_DOUT_TRISTATE = 1, + SI476X_DOUT_I2S_OUTPUT = 12, + SI476X_DOUT_I2S_INPUT = 13, +}; + +enum si476x_xout_config { + SI476X_XOUT_NOOP = 0, + SI476X_XOUT_TRISTATE = 1, + SI476X_XOUT_I2S_INPUT = 13, + SI476X_XOUT_MODE_SELECT = 23, +}; + +enum si476x_icin_config { + SI476X_ICIN_NOOP = 0, + SI476X_ICIN_TRISTATE = 1, + SI476X_ICIN_GPO1_HIGH = 2, + SI476X_ICIN_GPO1_LOW = 3, + SI476X_ICIN_IC_LINK = 30, +}; + +enum si476x_icip_config { + SI476X_ICIP_NOOP = 0, + SI476X_ICIP_TRISTATE = 1, + SI476X_ICIP_GPO2_HIGH = 2, + SI476X_ICIP_GPO2_LOW = 3, + SI476X_ICIP_IC_LINK = 30, +}; + +enum si476x_icon_config { + SI476X_ICON_NOOP = 0, + SI476X_ICON_TRISTATE = 1, + SI476X_ICON_I2S = 10, + SI476X_ICON_IC_LINK = 30, +}; + +enum si476x_icop_config { + SI476X_ICOP_NOOP = 0, + SI476X_ICOP_TRISTATE = 1, + SI476X_ICOP_I2S = 10, + SI476X_ICOP_IC_LINK = 30, +}; + + +enum si476x_lrout_config { + SI476X_LROUT_NOOP = 0, + SI476X_LROUT_TRISTATE = 1, + SI476X_LROUT_AUDIO = 2, + SI476X_LROUT_MPX = 3, +}; + + +enum si476x_intb_config { + SI476X_INTB_NOOP = 0, + SI476X_INTB_TRISTATE = 1, + SI476X_INTB_DAUDIO = 10, + SI476X_INTB_IRQ = 40, +}; + +enum si476x_a1_config { + SI476X_A1_NOOP = 0, + SI476X_A1_TRISTATE = 1, + SI476X_A1_IRQ = 40, +}; + + +struct si476x_pinmux { + enum si476x_dclk_config dclk; + enum si476x_dfs_config dfs; + enum si476x_dout_config dout; + enum si476x_xout_config xout; + + enum si476x_iqclk_config iqclk; + enum si476x_iqfs_config iqfs; + enum si476x_iout_config iout; + enum si476x_qout_config qout; + + enum si476x_icin_config icin; + enum si476x_icip_config icip; + enum si476x_icon_config icon; + enum si476x_icop_config icop; + + enum si476x_lrout_config lrout; + + enum si476x_intb_config intb; + enum si476x_a1_config a1; +}; + +enum si476x_ibias6x { + SI476X_IBIAS6X_OTHER = 0, + SI476X_IBIAS6X_RCVR1_NON_4MHZ_CLK = 1, +}; + +enum si476x_xstart { + SI476X_XSTART_MULTIPLE_TUNER = 0x11, + SI476X_XSTART_NORMAL = 0x77, +}; + +enum si476x_freq { + SI476X_FREQ_4_MHZ = 0, + SI476X_FREQ_37P209375_MHZ = 1, + SI476X_FREQ_36P4_MHZ = 2, + SI476X_FREQ_37P8_MHZ = 3, +}; + +enum si476x_xmode { + SI476X_XMODE_CRYSTAL_RCVR1 = 1, + SI476X_XMODE_EXT_CLOCK = 2, + SI476X_XMODE_CRYSTAL_RCVR2_3 = 3, +}; + +enum si476x_xbiashc { + SI476X_XBIASHC_SINGLE_RECEIVER = 0, + SI476X_XBIASHC_MULTIPLE_RECEIVER = 1, +}; + +enum si476x_xbias { + SI476X_XBIAS_RCVR2_3 = 0, + SI476X_XBIAS_4MHZ_RCVR1 = 3, + SI476X_XBIAS_RCVR1 = 7, +}; + +enum si476x_func { + SI476X_FUNC_BOOTLOADER = 0, + SI476X_FUNC_FM_RECEIVER = 1, + SI476X_FUNC_AM_RECEIVER = 2, + SI476X_FUNC_WB_RECEIVER = 3, +}; + + +/** + * @xcload: Selects the amount of additional on-chip capacitance to + * be connected between XTAL1 and gnd and between XTAL2 and + * GND. One half of the capacitance value shown here is the + * additional load capacitance presented to the xtal. The + * minimum step size is 0.277 pF. Recommended value is 0x28 + * but it will be layout dependent. Range is 0–0x3F i.e. + * (0–16.33 pF) + * @ctsien: enable CTSINT(interrupt request when CTS condition + * arises) when set + * @intsel: when set A1 pin becomes the interrupt pin; otherwise, + * INTB is the interrupt pin + * @func: selects the boot function of the device. I.e. + * SI476X_BOOTLOADER - Boot loader + * SI476X_FM_RECEIVER - FM receiver + * SI476X_AM_RECEIVER - AM receiver + * SI476X_WB_RECEIVER - Weatherband receiver + * @freq: oscillator's crystal frequency: + * SI476X_XTAL_37P209375_MHZ - 37.209375 Mhz + * SI476X_XTAL_36P4_MHZ - 36.4 Mhz + * SI476X_XTAL_37P8_MHZ - 37.8 Mhz + */ +struct si476x_power_up_args { + enum si476x_ibias6x ibias6x; + enum si476x_xstart xstart; + u8 xcload; + bool fastboot; + enum si476x_xbiashc xbiashc; + enum si476x_xbias xbias; + enum si476x_func func; + enum si476x_freq freq; + enum si476x_xmode xmode; +}; + + +/** + * enum si476x_phase_diversity_mode - possbile phase diversity modes + * for SI4764/5/6/7 chips. + * + * @SI476X_PHDIV_DISABLED: Phase diversity feature is + * disabled. + * @SI476X_PHDIV_PRIMARY_COMBINING: Tuner works as a primary tuner + * in combination with a + * secondary one. + * @SI476X_PHDIV_PRIMARY_ANTENNA: Tuner works as a primary tuner + * using only its own antenna. + * @SI476X_PHDIV_SECONDARY_ANTENNA: Tuner works as a primary tuner + * usning seconary tuner's antenna. + * @SI476X_PHDIV_SECONDARY_COMBINING: Tuner works as a secondary + * tuner in combination with the + * primary one. + */ +enum si476x_phase_diversity_mode { + SI476X_PHDIV_DISABLED = 0, + SI476X_PHDIV_PRIMARY_COMBINING = 1, + SI476X_PHDIV_PRIMARY_ANTENNA = 2, + SI476X_PHDIV_SECONDARY_ANTENNA = 3, + SI476X_PHDIV_SECONDARY_COMBINING = 5, +}; + + +/* + * Platform dependent definition + */ +struct si476x_platform_data { + int gpio_reset; /* < 0 if not used */ + + struct si476x_power_up_args power_up_parameters; + enum si476x_phase_diversity_mode diversity_mode; + + struct si476x_pinmux pinmux; +}; + + +#endif /* __SI476X_PLATFORM_H__ */ diff --git a/include/linux/mfd/si476x-reports.h b/include/linux/mfd/si476x-reports.h new file mode 100644 index 000000000000..e0b9455a79c0 --- /dev/null +++ b/include/linux/mfd/si476x-reports.h @@ -0,0 +1,163 @@ +/* + * include/media/si476x-platform.h -- Definitions of the data formats + * returned by debugfs hooks + * + * Copyright (C) 2013 Andrey Smirnov + * + * Author: Andrey Smirnov <andrew.smirnov@gmail.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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#ifndef __SI476X_REPORTS_H__ +#define __SI476X_REPORTS_H__ + +/** + * struct si476x_rsq_status - structure containing received signal + * quality + * @multhint: Multipath Detect High. + * true - Indicatedes that the value is below + * FM_RSQ_MULTIPATH_HIGH_THRESHOLD + * false - Indicatedes that the value is above + * FM_RSQ_MULTIPATH_HIGH_THRESHOLD + * @multlint: Multipath Detect Low. + * true - Indicatedes that the value is below + * FM_RSQ_MULTIPATH_LOW_THRESHOLD + * false - Indicatedes that the value is above + * FM_RSQ_MULTIPATH_LOW_THRESHOLD + * @snrhint: SNR Detect High. + * true - Indicatedes that the value is below + * FM_RSQ_SNR_HIGH_THRESHOLD + * false - Indicatedes that the value is above + * FM_RSQ_SNR_HIGH_THRESHOLD + * @snrlint: SNR Detect Low. + * true - Indicatedes that the value is below + * FM_RSQ_SNR_LOW_THRESHOLD + * false - Indicatedes that the value is above + * FM_RSQ_SNR_LOW_THRESHOLD + * @rssihint: RSSI Detect High. + * true - Indicatedes that the value is below + * FM_RSQ_RSSI_HIGH_THRESHOLD + * false - Indicatedes that the value is above + * FM_RSQ_RSSI_HIGH_THRESHOLD + * @rssilint: RSSI Detect Low. + * true - Indicatedes that the value is below + * FM_RSQ_RSSI_LOW_THRESHOLD + * false - Indicatedes that the value is above + * FM_RSQ_RSSI_LOW_THRESHOLD + * @bltf: Band Limit. + * Set if seek command hits the band limit or wrapped to + * the original frequency. + * @snr_ready: SNR measurement in progress. + * @rssiready: RSSI measurement in progress. + * @afcrl: Set if FREQOFF >= MAX_TUNE_ERROR + * @valid: Set if the channel is valid + * rssi < FM_VALID_RSSI_THRESHOLD + * snr < FM_VALID_SNR_THRESHOLD + * tune_error < FM_VALID_MAX_TUNE_ERROR + * @readfreq: Current tuned frequency. + * @freqoff: Signed frequency offset. + * @rssi: Received Signal Strength Indicator(dBuV). + * @snr: RF SNR Indicator(dB). + * @lassi: + * @hassi: Low/High side Adjacent(100 kHz) Channel Strength Indicator + * @mult: Multipath indicator + * @dev: Who knows? But values may vary. + * @readantcap: Antenna tuning capacity value. + * @assi: Adjacent Channel(+/- 200kHz) Strength Indicator + * @usn: Ultrasonic Noise Inticator in -DBFS + */ +struct si476x_rsq_status_report { + __u8 multhint, multlint; + __u8 snrhint, snrlint; + __u8 rssihint, rssilint; + __u8 bltf; + __u8 snr_ready; + __u8 rssiready; + __u8 injside; + __u8 afcrl; + __u8 valid; + + __u16 readfreq; + __s8 freqoff; + __s8 rssi; + __s8 snr; + __s8 issi; + __s8 lassi, hassi; + __s8 mult; + __u8 dev; + __u16 readantcap; + __s8 assi; + __s8 usn; + + __u8 pilotdev; + __u8 rdsdev; + __u8 assidev; + __u8 strongdev; + __u16 rdspi; +} __packed; + +/** + * si476x_acf_status_report - ACF report results + * + * @blend_int: If set, indicates that stereo separation has crossed + * below the blend threshold as set by FM_ACF_BLEND_THRESHOLD + * @hblend_int: If set, indicates that HiBlend cutoff frequency is + * lower than threshold as set by FM_ACF_HBLEND_THRESHOLD + * @hicut_int: If set, indicates that HiCut cutoff frequency is lower + * than the threshold set by ACF_ + + */ +struct si476x_acf_status_report { + __u8 blend_int; + __u8 hblend_int; + __u8 hicut_int; + __u8 chbw_int; + __u8 softmute_int; + __u8 smute; + __u8 smattn; + __u8 chbw; + __u8 hicut; + __u8 hiblend; + __u8 pilot; + __u8 stblend; +} __packed; + +enum si476x_fmagc { + SI476X_FMAGC_10K_OHM = 0, + SI476X_FMAGC_800_OHM = 1, + SI476X_FMAGC_400_OHM = 2, + SI476X_FMAGC_200_OHM = 4, + SI476X_FMAGC_100_OHM = 8, + SI476X_FMAGC_50_OHM = 16, + SI476X_FMAGC_25_OHM = 32, + SI476X_FMAGC_12P5_OHM = 64, + SI476X_FMAGC_6P25_OHM = 128, +}; + +struct si476x_agc_status_report { + __u8 mxhi; + __u8 mxlo; + __u8 lnahi; + __u8 lnalo; + __u8 fmagc1; + __u8 fmagc2; + __u8 pgagain; + __u8 fmwblang; +} __packed; + +struct si476x_rds_blockcount_report { + __u16 expected; + __u16 received; + __u16 uncorrectable; +} __packed; + +#endif /* __SI476X_REPORTS_H__ */ diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h index 383ac1512a39..48395a69a7e9 100644 --- a/include/linux/mfd/stmpe.h +++ b/include/linux/mfd/stmpe.h @@ -26,6 +26,7 @@ enum stmpe_partnum { STMPE801, STMPE811, STMPE1601, + STMPE1801, STMPE2401, STMPE2403, STMPE_NBR_PARTS @@ -39,6 +40,7 @@ enum { STMPE_IDX_CHIP_ID, STMPE_IDX_ICR_LSB, STMPE_IDX_IER_LSB, + STMPE_IDX_ISR_LSB, STMPE_IDX_ISR_MSB, STMPE_IDX_GPMR_LSB, STMPE_IDX_GPSR_LSB, @@ -49,6 +51,7 @@ enum { STMPE_IDX_GPFER_LSB, STMPE_IDX_GPAFR_U_MSB, STMPE_IDX_IEGPIOR_LSB, + STMPE_IDX_ISGPIOR_LSB, STMPE_IDX_ISGPIOR_MSB, STMPE_IDX_MAX, }; diff --git a/include/linux/mfd/stw481x.h b/include/linux/mfd/stw481x.h new file mode 100644 index 000000000000..eda121556e5d --- /dev/null +++ b/include/linux/mfd/stw481x.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011 ST-Ericsson SA + * Written on behalf of Linaro for ST-Ericsson + * + * Author: Linus Walleij <linus.walleij@linaro.org> + * + * License terms: GNU General Public License (GPL) version 2 + */ +#ifndef MFD_STW481X_H +#define MFD_STW481X_H + +#include <linux/i2c.h> +#include <linux/regulator/machine.h> +#include <linux/regmap.h> +#include <linux/bitops.h> + +/* These registers are accessed from more than one driver */ +#define STW_CONF1 0x11U +#define STW_CONF1_PDN_VMMC 0x01U +#define STW_CONF1_VMMC_MASK 0x0eU +#define STW_CONF1_VMMC_1_8V 0x02U +#define STW_CONF1_VMMC_2_85V 0x04U +#define STW_CONF1_VMMC_3V 0x06U +#define STW_CONF1_VMMC_1_85V 0x08U +#define STW_CONF1_VMMC_2_6V 0x0aU +#define STW_CONF1_VMMC_2_7V 0x0cU +#define STW_CONF1_VMMC_3_3V 0x0eU +#define STW_CONF1_MMC_LS_STATUS 0x10U +#define STW_PCTL_REG_LO 0x1eU +#define STW_PCTL_REG_HI 0x1fU +#define STW_CONF1_V_MONITORING 0x20U +#define STW_CONF1_IT_WARN 0x40U +#define STW_CONF1_PDN_VAUX 0x80U +#define STW_CONF2 0x20U +#define STW_CONF2_MASK_TWARN 0x01U +#define STW_CONF2_VMMC_EXT 0x02U +#define STW_CONF2_MASK_IT_WAKE_UP 0x04U +#define STW_CONF2_GPO1 0x08U +#define STW_CONF2_GPO2 0x10U +#define STW_VCORE_SLEEP 0x21U + +/** + * struct stw481x - state holder for the Stw481x drivers + * @mutex: mutex to serialize I2C accesses + * @i2c_client: corresponding I2C client + * @regulator: regulator device for regulator children + * @map: regmap handle to access device registers + */ +struct stw481x { + struct mutex lock; + struct i2c_client *client; + struct regulator_dev *vmmc_regulator; + struct regmap *map; +}; + +#endif diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h index 6aeb6b8da64d..b473577f36db 100644 --- a/include/linux/mfd/syscon.h +++ b/include/linux/mfd/syscon.h @@ -15,8 +15,11 @@ #ifndef __LINUX_MFD_SYSCON_H__ #define __LINUX_MFD_SYSCON_H__ +struct device_node; + extern struct regmap *syscon_node_to_regmap(struct device_node *np); extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s); +extern struct regmap *syscon_regmap_lookup_by_pdevname(const char *s); extern struct regmap *syscon_regmap_lookup_by_phandle( struct device_node *np, const char *property); diff --git a/include/linux/mfd/syscon/clps711x.h b/include/linux/mfd/syscon/clps711x.h new file mode 100644 index 000000000000..26355abae515 --- /dev/null +++ b/include/linux/mfd/syscon/clps711x.h @@ -0,0 +1,94 @@ +/* + * CLPS711X system register bits definitions + * + * Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru> + * + * 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_MFD_SYSCON_CLPS711X_H_ +#define _LINUX_MFD_SYSCON_CLPS711X_H_ + +#define SYSCON_OFFSET (0x00) +#define SYSFLG_OFFSET (0x40) + +#define SYSCON1_KBDSCAN(x) ((x) & 15) +#define SYSCON1_KBDSCAN_MASK (15) +#define SYSCON1_TC1M (1 << 4) +#define SYSCON1_TC1S (1 << 5) +#define SYSCON1_TC2M (1 << 6) +#define SYSCON1_TC2S (1 << 7) +#define SYSCON1_BZTOG (1 << 9) +#define SYSCON1_BZMOD (1 << 10) +#define SYSCON1_DBGEN (1 << 11) +#define SYSCON1_LCDEN (1 << 12) +#define SYSCON1_CDENTX (1 << 13) +#define SYSCON1_CDENRX (1 << 14) +#define SYSCON1_SIREN (1 << 15) +#define SYSCON1_ADCKSEL(x) (((x) & 3) << 16) +#define SYSCON1_ADCKSEL_MASK (3 << 16) +#define SYSCON1_EXCKEN (1 << 18) +#define SYSCON1_WAKEDIS (1 << 19) +#define SYSCON1_IRTXM (1 << 20) + +#define SYSCON2_SERSEL (1 << 0) +#define SYSCON2_KBD6 (1 << 1) +#define SYSCON2_DRAMZ (1 << 2) +#define SYSCON2_KBWEN (1 << 3) +#define SYSCON2_SS2TXEN (1 << 4) +#define SYSCON2_PCCARD1 (1 << 5) +#define SYSCON2_PCCARD2 (1 << 6) +#define SYSCON2_SS2RXEN (1 << 7) +#define SYSCON2_SS2MAEN (1 << 9) +#define SYSCON2_OSTB (1 << 12) +#define SYSCON2_CLKENSL (1 << 13) +#define SYSCON2_BUZFREQ (1 << 14) + +#define SYSCON3_ADCCON (1 << 0) +#define SYSCON3_CLKCTL0 (1 << 1) +#define SYSCON3_CLKCTL1 (1 << 2) +#define SYSCON3_DAISEL (1 << 3) +#define SYSCON3_ADCCKNSEN (1 << 4) +#define SYSCON3_VERSN(x) (((x) >> 5) & 7) +#define SYSCON3_VERSN_MASK (7 << 5) +#define SYSCON3_FASTWAKE (1 << 8) +#define SYSCON3_DAIEN (1 << 9) +#define SYSCON3_128FS SYSCON3_DAIEN +#define SYSCON3_ENPD67 (1 << 10) + +#define SYSCON_UARTEN (1 << 8) + +#define SYSFLG1_MCDR (1 << 0) +#define SYSFLG1_DCDET (1 << 1) +#define SYSFLG1_WUDR (1 << 2) +#define SYSFLG1_WUON (1 << 3) +#define SYSFLG1_CTS (1 << 8) +#define SYSFLG1_DSR (1 << 9) +#define SYSFLG1_DCD (1 << 10) +#define SYSFLG1_NBFLG (1 << 12) +#define SYSFLG1_RSTFLG (1 << 13) +#define SYSFLG1_PFFLG (1 << 14) +#define SYSFLG1_CLDFLG (1 << 15) +#define SYSFLG1_CRXFE (1 << 24) +#define SYSFLG1_CTXFF (1 << 25) +#define SYSFLG1_SSIBUSY (1 << 26) +#define SYSFLG1_ID (1 << 29) +#define SYSFLG1_VERID(x) (((x) >> 30) & 3) +#define SYSFLG1_VERID_MASK (3 << 30) + +#define SYSFLG2_SSRXOF (1 << 0) +#define SYSFLG2_RESVAL (1 << 1) +#define SYSFLG2_RESFRM (1 << 2) +#define SYSFLG2_SS2RXFE (1 << 3) +#define SYSFLG2_SS2TXFF (1 << 4) +#define SYSFLG2_SS2TXUF (1 << 5) +#define SYSFLG2_CKMODE (1 << 6) + +#define SYSFLG_UBUSY (1 << 11) +#define SYSFLG_URXFE (1 << 22) +#define SYSFLG_UTXFF (1 << 23) + +#endif diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h index dab34a1deb2c..7086b2248c8f 100644 --- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h +++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h @@ -103,15 +103,15 @@ #define IMX6Q_GPR1_EXC_MON_MASK BIT(22) #define IMX6Q_GPR1_EXC_MON_OKAY 0x0 #define IMX6Q_GPR1_EXC_MON_SLVE BIT(22) -#define IMX6Q_GPR1_MIPI_IPU2_SEL_MASK BIT(21) -#define IMX6Q_GPR1_MIPI_IPU2_SEL_GASKET 0x0 -#define IMX6Q_GPR1_MIPI_IPU2_SEL_IOMUX BIT(21) -#define IMX6Q_GPR1_MIPI_IPU1_MUX_MASK BIT(20) -#define IMX6Q_GPR1_MIPI_IPU1_MUX_GASKET 0x0 -#define IMX6Q_GPR1_MIPI_IPU1_MUX_IOMUX BIT(20) -#define IMX6Q_GPR1_MIPI_IPU2_MUX_MASK BIT(19) +#define IMX6Q_GPR1_ENET_CLK_SEL_MASK BIT(21) +#define IMX6Q_GPR1_ENET_CLK_SEL_PAD 0 +#define IMX6Q_GPR1_ENET_CLK_SEL_ANATOP BIT(21) +#define IMX6Q_GPR1_MIPI_IPU2_MUX_MASK BIT(20) #define IMX6Q_GPR1_MIPI_IPU2_MUX_GASKET 0x0 -#define IMX6Q_GPR1_MIPI_IPU2_MUX_IOMUX BIT(19) +#define IMX6Q_GPR1_MIPI_IPU2_MUX_IOMUX BIT(20) +#define IMX6Q_GPR1_MIPI_IPU1_MUX_MASK BIT(19) +#define IMX6Q_GPR1_MIPI_IPU1_MUX_GASKET 0x0 +#define IMX6Q_GPR1_MIPI_IPU1_MUX_IOMUX BIT(19) #define IMX6Q_GPR1_PCIE_TEST_PD BIT(18) #define IMX6Q_GPR1_IPU_VPU_MUX_MASK BIT(17) #define IMX6Q_GPR1_IPU_VPU_MUX_IPU1 0x0 @@ -279,41 +279,93 @@ #define IMX6Q_GPR13_CAN2_STOP_REQ BIT(29) #define IMX6Q_GPR13_CAN1_STOP_REQ BIT(28) #define IMX6Q_GPR13_ENET_STOP_REQ BIT(27) -#define IMX6Q_GPR13_SATA_PHY_8_MASK (0x7 << 24) -#define IMX6Q_GPR13_SATA_PHY_8_0_5_DB (0x0 << 24) -#define IMX6Q_GPR13_SATA_PHY_8_1_0_DB (0x1 << 24) -#define IMX6Q_GPR13_SATA_PHY_8_1_5_DB (0x2 << 24) -#define IMX6Q_GPR13_SATA_PHY_8_2_0_DB (0x3 << 24) -#define IMX6Q_GPR13_SATA_PHY_8_2_5_DB (0x4 << 24) -#define IMX6Q_GPR13_SATA_PHY_8_3_0_DB (0x5 << 24) -#define IMX6Q_GPR13_SATA_PHY_8_3_5_DB (0x6 << 24) -#define IMX6Q_GPR13_SATA_PHY_8_4_0_DB (0x7 << 24) -#define IMX6Q_GPR13_SATA_PHY_7_MASK (0x1f << 19) -#define IMX6Q_GPR13_SATA_PHY_7_SATA1I (0x10 << 19) -#define IMX6Q_GPR13_SATA_PHY_7_SATA1M (0x10 << 19) -#define IMX6Q_GPR13_SATA_PHY_7_SATA1X (0x1a << 19) -#define IMX6Q_GPR13_SATA_PHY_7_SATA2I (0x12 << 19) -#define IMX6Q_GPR13_SATA_PHY_7_SATA2M (0x12 << 19) -#define IMX6Q_GPR13_SATA_PHY_7_SATA2X (0x1a << 19) -#define IMX6Q_GPR13_SATA_PHY_6_MASK (0x7 << 16) -#define IMX6Q_GPR13_SATA_SPEED_MASK BIT(15) -#define IMX6Q_GPR13_SATA_SPEED_1P5G 0x0 -#define IMX6Q_GPR13_SATA_SPEED_3P0G BIT(15) -#define IMX6Q_GPR13_SATA_PHY_5 BIT(14) -#define IMX6Q_GPR13_SATA_PHY_4_MASK (0x7 << 11) -#define IMX6Q_GPR13_SATA_PHY_4_16_16 (0x0 << 11) -#define IMX6Q_GPR13_SATA_PHY_4_14_16 (0x1 << 11) -#define IMX6Q_GPR13_SATA_PHY_4_12_16 (0x2 << 11) -#define IMX6Q_GPR13_SATA_PHY_4_10_16 (0x3 << 11) -#define IMX6Q_GPR13_SATA_PHY_4_9_16 (0x4 << 11) -#define IMX6Q_GPR13_SATA_PHY_4_8_16 (0x5 << 11) -#define IMX6Q_GPR13_SATA_PHY_3_MASK (0xf << 7) -#define IMX6Q_GPR13_SATA_PHY_3_OFF 0x7 -#define IMX6Q_GPR13_SATA_PHY_2_MASK (0x1f << 2) -#define IMX6Q_GPR13_SATA_PHY_2_OFF 0x2 -#define IMX6Q_GPR13_SATA_PHY_1_MASK (0x3 << 0) -#define IMX6Q_GPR13_SATA_PHY_1_FAST (0x0 << 0) -#define IMX6Q_GPR13_SATA_PHY_1_MED (0x1 << 0) -#define IMX6Q_GPR13_SATA_PHY_1_SLOW (0x2 << 0) +#define IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK (0x7 << 24) +#define IMX6Q_GPR13_SATA_RX_EQ_VAL_0_5_DB (0x0 << 24) +#define IMX6Q_GPR13_SATA_RX_EQ_VAL_1_0_DB (0x1 << 24) +#define IMX6Q_GPR13_SATA_RX_EQ_VAL_1_5_DB (0x2 << 24) +#define IMX6Q_GPR13_SATA_RX_EQ_VAL_2_0_DB (0x3 << 24) +#define IMX6Q_GPR13_SATA_RX_EQ_VAL_2_5_DB (0x4 << 24) +#define IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB (0x5 << 24) +#define IMX6Q_GPR13_SATA_RX_EQ_VAL_3_5_DB (0x6 << 24) +#define IMX6Q_GPR13_SATA_RX_EQ_VAL_4_0_DB (0x7 << 24) +#define IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK (0x1f << 19) +#define IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA1I (0x10 << 19) +#define IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA1M (0x10 << 19) +#define IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA1X (0x1a << 19) +#define IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2I (0x12 << 19) +#define IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M (0x12 << 19) +#define IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2X (0x1a << 19) +#define IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK (0x7 << 16) +#define IMX6Q_GPR13_SATA_RX_DPLL_MODE_1P_1F (0x0 << 16) +#define IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_2F (0x1 << 16) +#define IMX6Q_GPR13_SATA_RX_DPLL_MODE_1P_4F (0x2 << 16) +#define IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F (0x3 << 16) +#define IMX6Q_GPR13_SATA_SPD_MODE_MASK BIT(15) +#define IMX6Q_GPR13_SATA_SPD_MODE_1P5G 0x0 +#define IMX6Q_GPR13_SATA_SPD_MODE_3P0G BIT(15) +#define IMX6Q_GPR13_SATA_MPLL_SS_EN BIT(14) +#define IMX6Q_GPR13_SATA_TX_ATTEN_MASK (0x7 << 11) +#define IMX6Q_GPR13_SATA_TX_ATTEN_16_16 (0x0 << 11) +#define IMX6Q_GPR13_SATA_TX_ATTEN_14_16 (0x1 << 11) +#define IMX6Q_GPR13_SATA_TX_ATTEN_12_16 (0x2 << 11) +#define IMX6Q_GPR13_SATA_TX_ATTEN_10_16 (0x3 << 11) +#define IMX6Q_GPR13_SATA_TX_ATTEN_9_16 (0x4 << 11) +#define IMX6Q_GPR13_SATA_TX_ATTEN_8_16 (0x5 << 11) +#define IMX6Q_GPR13_SATA_TX_BOOST_MASK (0xf << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_0_00_DB (0x0 << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_0_37_DB (0x1 << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_0_74_DB (0x2 << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_1_11_DB (0x3 << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_1_48_DB (0x4 << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_1_85_DB (0x5 << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_2_22_DB (0x6 << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_2_59_DB (0x7 << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_2_96_DB (0x8 << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB (0x9 << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_3_70_DB (0xa << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_4_07_DB (0xb << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_4_44_DB (0xc << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_4_81_DB (0xd << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_5_28_DB (0xe << 7) +#define IMX6Q_GPR13_SATA_TX_BOOST_5_75_DB (0xf << 7) +#define IMX6Q_GPR13_SATA_TX_LVL_MASK (0x1f << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_0_937_V (0x00 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_0_947_V (0x01 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_0_957_V (0x02 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_0_966_V (0x03 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_0_976_V (0x04 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_0_986_V (0x05 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_0_996_V (0x06 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_005_V (0x07 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_015_V (0x08 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_025_V (0x09 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_035_V (0x0a << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_045_V (0x0b << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_054_V (0x0c << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_064_V (0x0d << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_074_V (0x0e << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_084_V (0x0f << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_094_V (0x10 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_104_V (0x11 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_113_V (0x12 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_123_V (0x13 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_133_V (0x14 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_143_V (0x15 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_152_V (0x16 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_162_V (0x17 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_172_V (0x18 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_182_V (0x19 << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_191_V (0x1a << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_201_V (0x1b << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_211_V (0x1c << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_221_V (0x1d << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_230_V (0x1e << 2) +#define IMX6Q_GPR13_SATA_TX_LVL_1_240_V (0x1f << 2) +#define IMX6Q_GPR13_SATA_MPLL_CLK_EN BIT(1) +#define IMX6Q_GPR13_SATA_TX_EDGE_RATE BIT(0) + +/* For imx6sl iomux gpr register field define */ +#define IMX6SL_GPR1_FEC_CLOCK_MUX1_SEL_MASK (0x3 << 17) +#define IMX6SL_GPR1_FEC_CLOCK_MUX2_SEL_MASK (0x1 << 14) #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */ diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h index c79ad5d2f271..d498d98f0c2c 100644 --- a/include/linux/mfd/ti_am335x_tscadc.h +++ b/include/linux/mfd/ti_am335x_tscadc.h @@ -30,8 +30,8 @@ #define REG_IDLECONFIG 0x058 #define REG_CHARGECONFIG 0x05C #define REG_CHARGEDELAY 0x060 -#define REG_STEPCONFIG(n) (0x64 + ((n - 1) * 8)) -#define REG_STEPDELAY(n) (0x68 + ((n - 1) * 8)) +#define REG_STEPCONFIG(n) (0x64 + ((n) * 8)) +#define REG_STEPDELAY(n) (0x68 + ((n) * 8)) #define REG_FIFO0CNT 0xE4 #define REG_FIFO0THR 0xE8 #define REG_FIFO1CNT 0xF0 @@ -46,18 +46,24 @@ /* Step Enable */ #define STEPENB_MASK (0x1FFFF << 0) #define STEPENB(val) ((val) << 0) +#define ENB(val) (1 << (val)) #define STPENB_STEPENB STEPENB(0x1FFFF) #define STPENB_STEPENB_TC STEPENB(0x1FFF) /* IRQ enable */ #define IRQENB_HW_PEN BIT(0) #define IRQENB_FIFO0THRES BIT(2) +#define IRQENB_FIFO0OVRRUN BIT(3) +#define IRQENB_FIFO0UNDRFLW BIT(4) #define IRQENB_FIFO1THRES BIT(5) +#define IRQENB_FIFO1OVRRUN BIT(6) +#define IRQENB_FIFO1UNDRFLW BIT(7) #define IRQENB_PENUP BIT(9) /* Step Configuration */ #define STEPCONFIG_MODE_MASK (3 << 0) #define STEPCONFIG_MODE(val) ((val) << 0) +#define STEPCONFIG_MODE_SWCNT STEPCONFIG_MODE(1) #define STEPCONFIG_MODE_HWSYNC STEPCONFIG_MODE(2) #define STEPCONFIG_AVG_MASK (7 << 2) #define STEPCONFIG_AVG(val) ((val) << 2) @@ -73,8 +79,6 @@ #define STEPCONFIG_INM_ADCREFM STEPCONFIG_INM(8) #define STEPCONFIG_INP_MASK (0xF << 19) #define STEPCONFIG_INP(val) ((val) << 19) -#define STEPCONFIG_INP_AN2 STEPCONFIG_INP(2) -#define STEPCONFIG_INP_AN3 STEPCONFIG_INP(3) #define STEPCONFIG_INP_AN4 STEPCONFIG_INP(4) #define STEPCONFIG_INP_ADCREFM STEPCONFIG_INP(8) #define STEPCONFIG_FIFO1 BIT(26) @@ -96,7 +100,6 @@ #define STEPCHARGE_INM_AN1 STEPCHARGE_INM(1) #define STEPCHARGE_INP_MASK (0xF << 19) #define STEPCHARGE_INP(val) ((val) << 19) -#define STEPCHARGE_INP_AN1 STEPCHARGE_INP(1) #define STEPCHARGE_RFM_MASK (3 << 23) #define STEPCHARGE_RFM(val) ((val) << 23) #define STEPCHARGE_RFM_XNUR STEPCHARGE_RFM(1) @@ -118,29 +121,46 @@ #define CNTRLREG_8WIRE CNTRLREG_AFE_CTRL(3) #define CNTRLREG_TSCENB BIT(7) +/* FIFO READ Register */ +#define FIFOREAD_DATA_MASK (0xfff << 0) +#define FIFOREAD_CHNLID_MASK (0xf << 16) + +/* Sequencer Status */ +#define SEQ_STATUS BIT(5) + #define ADC_CLK 3000000 -#define MAX_CLK_DIV 7 #define TOTAL_STEPS 16 #define TOTAL_CHANNELS 8 +#define FIFO1_THRESHOLD 19 -#define TSCADC_CELLS 2 - -enum tscadc_cells { - TSC_CELL, - ADC_CELL, -}; +/* + * time in us for processing a single channel, calculated as follows: + * + * num cycles = open delay + (sample delay + conv time) * averaging + * + * num cycles: 152 + (1 + 13) * 16 = 376 + * + * clock frequency: 26MHz / 8 = 3.25MHz + * clock period: 1 / 3.25MHz = 308ns + * + * processing time: 376 * 308ns = 116us + */ +#define IDLE_TIMEOUT 116 /* microsec */ -struct mfd_tscadc_board { - struct tsc_data *tsc_init; - struct adc_data *adc_init; -}; +#define TSCADC_CELLS 2 struct ti_tscadc_dev { struct device *dev; struct regmap *regmap_tscadc; void __iomem *tscadc_base; int irq; + int used_cells; /* 1-2 */ + int tsc_cell; /* -1 if not used */ + int adc_cell; /* -1 if not used */ struct mfd_cell cells[TSCADC_CELLS]; + u32 reg_se_cache; + spinlock_t reg_lock; + unsigned int clk_div; /* tsc device */ struct titsc *tsc; @@ -149,4 +169,15 @@ struct ti_tscadc_dev { struct adc_device *adc; }; +static inline struct ti_tscadc_dev *ti_tscadc_dev_get(struct platform_device *p) +{ + struct ti_tscadc_dev **tscadc_dev = p->dev.platform_data; + + return *tscadc_dev; +} + +void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc); +void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val); +void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val); + #endif diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index 99bf3e665997..b22883d60500 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h @@ -81,10 +81,15 @@ int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base); void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state); void tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state); +struct dma_chan; + struct tmio_mmc_dma { void *chan_priv_tx; void *chan_priv_rx; + int slave_id_tx; + int slave_id_rx; int alignment_shift; + bool (*filter)(struct dma_chan *chan, void *arg); }; struct tmio_mmc_host; @@ -103,7 +108,6 @@ struct tmio_mmc_data { unsigned int cd_gpio; void (*set_pwr)(struct platform_device *host, int state); void (*set_clk_div)(struct platform_device *host, int state); - int (*get_cd)(struct platform_device *host); int (*write16_hook)(struct tmio_mmc_host *host, int addr); /* clock management callbacks */ int (*clk_enable)(struct platform_device *pdev, unsigned int *f); diff --git a/include/linux/mfd/tps6507x.h b/include/linux/mfd/tps6507x.h index c923e4864f55..c2ae56933539 100644 --- a/include/linux/mfd/tps6507x.h +++ b/include/linux/mfd/tps6507x.h @@ -163,7 +163,6 @@ struct tps6507x_dev { /* Client devices */ struct tps6507x_pmic *pmic; - struct tps6507x_ts *ts; }; #endif /* __LINUX_MFD_TPS6507X_H */ diff --git a/include/linux/mfd/tps65090.h b/include/linux/mfd/tps65090.h index 6694cf43e8b8..3f43069413e7 100644 --- a/include/linux/mfd/tps65090.h +++ b/include/linux/mfd/tps65090.h @@ -27,6 +27,7 @@ /* TPS65090 IRQs */ enum { + TPS65090_IRQ_INTERRUPT, TPS65090_IRQ_VAC_STATUS_CHANGE, TPS65090_IRQ_VSYS_STATUS_CHANGE, TPS65090_IRQ_BAT_STATUS_CHANGE, @@ -86,6 +87,11 @@ struct tps65090_regulator_plat_data { struct tps65090_platform_data { int irq_base; + + char **supplied_to; + size_t num_supplicants; + int enable_low_current_chrg; + struct tps65090_regulator_plat_data *reg_pdata[TPS65090_REGULATOR_MAX]; }; diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h index 290762f93930..a5a7f0130e96 100644 --- a/include/linux/mfd/tps65217.h +++ b/include/linux/mfd/tps65217.h @@ -228,6 +228,7 @@ enum tps65217_bl_fdim { struct tps65217_bl_pdata { enum tps65217_bl_isel isel; enum tps65217_bl_fdim fdim; + int dft_brightness; }; /** @@ -243,24 +244,6 @@ struct tps65217_board { }; /** - * struct tps_info - packages regulator constraints - * @name: Voltage regulator name - * @min_uV: minimum micro volts - * @max_uV: minimum micro volts - * @vsel_to_uv: Function pointer to get voltage from selector - * @uv_to_vsel: Function pointer to get selector from voltage - * - * This data is used to check the regualtor voltage limits while setting. - */ -struct tps_info { - const char *name; - int min_uV; - int max_uV; - int (*vsel_to_uv)(unsigned int vsel); - int (*uv_to_vsel)(int uV, unsigned int *vsel); -}; - -/** * struct tps65217 - tps65217 sub-driver chip access routines * * Device data may be used to access the TPS65217 chip @@ -272,7 +255,6 @@ struct tps65217 { unsigned int id; struct regulator_desc desc[TPS65217_NUM_REGULATOR]; struct regulator_dev *rdev[TPS65217_NUM_REGULATOR]; - struct tps_info *info[TPS65217_NUM_REGULATOR]; struct regmap *regmap; }; diff --git a/include/linux/mfd/tps65912.h b/include/linux/mfd/tps65912.h index aaceab402ec5..6d309032dc0d 100644 --- a/include/linux/mfd/tps65912.h +++ b/include/linux/mfd/tps65912.h @@ -323,5 +323,6 @@ int tps65912_device_init(struct tps65912 *tps65912); void tps65912_device_exit(struct tps65912 *tps65912); int tps65912_irq_init(struct tps65912 *tps65912, int irq, struct tps65912_platform_data *pdata); +int tps65912_irq_exit(struct tps65912 *tps65912); #endif /* __LINUX_MFD_TPS65912_H */ diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h index 94ac944d12f0..81f639bc1ae6 100644 --- a/include/linux/mfd/twl6040.h +++ b/include/linux/mfd/twl6040.h @@ -125,8 +125,15 @@ #define TWL6040_HSDACENA (1 << 0) #define TWL6040_HSDACMODE (1 << 1) +#define TWL6040_HSDRVENA (1 << 2) #define TWL6040_HSDRVMODE (1 << 3) +/* HFLCTL/R (0x14/0x16) fields */ + +#define TWL6040_HFDACENA (1 << 0) +#define TWL6040_HFPGAENA (1 << 1) +#define TWL6040_HFDRVENA (1 << 4) + /* VIBCTLL/R (0x18/0x1A) fields */ #define TWL6040_VIBENA (1 << 0) @@ -178,6 +185,7 @@ #define TWL6040_GPO_MAX 3 +/* TODO: All platform data struct can be removed */ struct twl6040_codec_data { u16 hs_left_step; u16 hs_right_step; @@ -222,7 +230,6 @@ struct twl6040 { int audpwron; int power_count; int rev; - u8 vibra_ctrl_cache[2]; /* PLL configuration */ int pll; diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h index 28af41756360..88f90cbf8e6a 100644 --- a/include/linux/mfd/ucb1x00.h +++ b/include/linux/mfd/ucb1x00.h @@ -10,6 +10,7 @@ #ifndef UCB1200_H #define UCB1200_H +#include <linux/device.h> #include <linux/mfd/mcp.h> #include <linux/gpio.h> #include <linux/mutex.h> diff --git a/include/linux/mfd/wm831x/auxadc.h b/include/linux/mfd/wm831x/auxadc.h index b132067e9e99..867aa23f9370 100644 --- a/include/linux/mfd/wm831x/auxadc.h +++ b/include/linux/mfd/wm831x/auxadc.h @@ -15,6 +15,8 @@ #ifndef __MFD_WM831X_AUXADC_H__ #define __MFD_WM831X_AUXADC_H__ +struct wm831x; + /* * R16429 (0x402D) - AuxADC Data */ diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index 4a3b83a77614..76c22648436f 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h @@ -20,6 +20,7 @@ #include <linux/irqdomain.h> #include <linux/list.h> #include <linux/regmap.h> +#include <linux/mfd/wm831x/auxadc.h> /* * Register values. @@ -355,7 +356,6 @@ enum wm831x_parent { }; struct wm831x; -enum wm831x_auxadc; typedef int (*wm831x_auxadc_read_fn)(struct wm831x *wm831x, enum wm831x_auxadc input); diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h index ae5c249530b4..eefafa62d304 100644 --- a/include/linux/mfd/wm8994/core.h +++ b/include/linux/mfd/wm8994/core.h @@ -29,6 +29,7 @@ enum wm8994_type { struct regulator_dev; struct regulator_bulk_data; +struct irq_domain; #define WM8994_NUM_GPIO_REGS 11 #define WM8994_NUM_LDO_REGS 2 @@ -55,8 +56,6 @@ struct regulator_bulk_data; #define WM8994_IRQ_GPIO(x) (x + WM8994_IRQ_TEMP_WARN) struct wm8994 { - struct mutex irq_lock; - struct wm8994_pdata pdata; enum wm8994_type type; @@ -73,6 +72,7 @@ struct wm8994 { int irq; struct regmap_irq_chip_data *irq_data; + struct irq_domain *edge_irq; /* Used over suspend/resume */ bool suspended; @@ -83,16 +83,43 @@ struct wm8994 { }; /* Device I/O API */ -int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg); -int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg, - unsigned short val); -int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg, - unsigned short mask, unsigned short val); -int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, - int count, u16 *buf); -int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg, - int count, const u16 *buf); +static inline int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg) +{ + unsigned int val; + int ret; + + ret = regmap_read(wm8994->regmap, reg, &val); + + if (ret < 0) + return ret; + else + return val; +} + +static inline int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg, + unsigned short val) +{ + return regmap_write(wm8994->regmap, reg, val); +} + +static inline int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, + int count, u16 *buf) +{ + return regmap_bulk_read(wm8994->regmap, reg, buf, count); +} + +static inline int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg, + int count, const u16 *buf) +{ + return regmap_raw_write(wm8994->regmap, reg, buf, count * sizeof(u16)); +} + +static inline int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg, + unsigned short mask, unsigned short val) +{ + return regmap_update_bits(wm8994->regmap, reg, mask, val); +} /* Helper to save on boilerplate */ static inline int wm8994_request_irq(struct wm8994 *wm8994, int irq, diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 8e21a094836d..90c60524a496 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -17,6 +17,7 @@ #define WM8994_NUM_LDO 2 #define WM8994_NUM_GPIO 11 +#define WM8994_NUM_AIF 3 struct wm8994_ldo_pdata { /** GPIOs to enable regulator, 0 or less if not available */ @@ -181,6 +182,11 @@ struct wm8994_pdata { */ int micdet_delay; + /* Delay between microphone detect completing and reporting on + * insert (specified in ms) + */ + int mic_id_delay; + /* IRQ for microphone detection if brought out directly as a * signal. */ @@ -215,6 +221,18 @@ struct wm8994_pdata { * system. */ bool spkmode_pu; + + /** + * Maximum number of channels clocks will be generated for, + * useful for systems where and I2S bus with multiple data + * lines is mastered. + */ + int max_channels_clocked[WM8994_NUM_AIF]; + + /** + * GPIO for the IRQ pin if host only supports edge triggering + */ + int irq_gpio; }; #endif diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h index 053548961c15..db8cef3d5321 100644 --- a/include/linux/mfd/wm8994/registers.h +++ b/include/linux/mfd/wm8994/registers.h @@ -2668,6 +2668,10 @@ /* * R772 (0x304) - AIF1ADC LRCLK */ +#define WM8958_AIF1_LRCLK_INV 0x1000 /* AIF1_LRCLK_INV */ +#define WM8958_AIF1_LRCLK_INV_MASK 0x1000 /* AIF1_LRCLK_INV */ +#define WM8958_AIF1_LRCLK_INV_SHIFT 12 /* AIF1_LRCLK_INV */ +#define WM8958_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */ #define WM8994_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */ #define WM8994_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */ #define WM8994_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */ @@ -2679,6 +2683,10 @@ /* * R773 (0x305) - AIF1DAC LRCLK */ +#define WM8958_AIF1_LRCLK_INV 0x1000 /* AIF1_LRCLK_INV */ +#define WM8958_AIF1_LRCLK_INV_MASK 0x1000 /* AIF1_LRCLK_INV */ +#define WM8958_AIF1_LRCLK_INV_SHIFT 12 /* AIF1_LRCLK_INV */ +#define WM8958_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */ #define WM8994_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */ #define WM8994_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */ #define WM8994_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */ diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h index 9dbb41a4e250..ad05ce60c1c9 100644 --- a/include/linux/micrel_phy.h +++ b/include/linux/micrel_phy.h @@ -17,8 +17,10 @@ #define PHY_ID_KSZ8873MLL 0x000e7237 #define PHY_ID_KSZ9021 0x00221610 +#define PHY_ID_KSZ9021RLRN 0x00221611 #define PHY_ID_KS8737 0x00221720 #define PHY_ID_KSZ8021 0x00221555 +#define PHY_ID_KSZ8031 0x00221556 #define PHY_ID_KSZ8041 0x00221510 #define PHY_ID_KSZ8051 0x00221550 /* same id: ks8001 Rev. A/B, and ks8721 Rev 3. */ @@ -34,4 +36,9 @@ /* struct phy_device dev_flags definitions */ #define MICREL_PHY_50MHZ_CLK 0x00000001 +#define MICREL_KSZ9021_EXTREG_CTRL 0xB +#define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC +#define MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW 0x104 +#define MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW 0x105 + #endif /* _MICREL_PHY_H */ diff --git a/include/linux/migrate.h b/include/linux/migrate.h index a405d3dc0f61..8d3c57fdf221 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -41,8 +41,6 @@ extern int migrate_page(struct address_space *, struct page *, struct page *, enum migrate_mode); extern int migrate_pages(struct list_head *l, new_page_t x, unsigned long private, enum migrate_mode mode, int reason); -extern int migrate_huge_page(struct page *, new_page_t x, - unsigned long private, enum migrate_mode mode); extern int fail_migrate_page(struct address_space *, struct page *, struct page *); @@ -55,6 +53,9 @@ extern int migrate_vmas(struct mm_struct *mm, extern void migrate_page_copy(struct page *newpage, struct page *page); extern int migrate_huge_page_move_mapping(struct address_space *mapping, struct page *newpage, struct page *page); +extern int migrate_page_move_mapping(struct address_space *mapping, + struct page *newpage, struct page *page, + struct buffer_head *head, enum migrate_mode mode); #else static inline void putback_lru_pages(struct list_head *l) {} @@ -62,9 +63,6 @@ static inline void putback_movable_pages(struct list_head *l) {} static inline int migrate_pages(struct list_head *l, new_page_t x, unsigned long private, enum migrate_mode mode, int reason) { return -ENOSYS; } -static inline int migrate_huge_page(struct page *page, new_page_t x, - unsigned long private, enum migrate_mode mode) - { return -ENOSYS; } static inline int migrate_prep(void) { return -ENOSYS; } static inline int migrate_prep_local(void) { return -ENOSYS; } diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index 09c2300ddb37..c8cf093d8b71 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -31,6 +31,7 @@ #define I2O_MINOR 166 #define MICROCODE_MINOR 184 #define TUN_MINOR 200 +#define CUSE_MINOR 203 #define MWAVE_MINOR 219 /* ACP/Mwave Modem */ #define MPT_MINOR 220 #define MPT2SAS_MINOR 221 diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index 260695186256..cd1fdf75103b 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h @@ -34,6 +34,7 @@ #define MLX4_CMD_H #include <linux/dma-mapping.h> +#include <linux/if_link.h> enum { /* initialization and general commands */ @@ -68,6 +69,7 @@ enum { MLX4_CMD_SET_ICM_SIZE = 0xffd, /*master notify fw on finish for slave's flr*/ MLX4_CMD_INFORM_FLR_DONE = 0x5b, + MLX4_CMD_GET_OP_REQ = 0x59, /* TPT commands */ MLX4_CMD_SW2HW_MPT = 0xd, @@ -110,6 +112,7 @@ enum { MLX4_CMD_INIT2INIT_QP = 0x2d, MLX4_CMD_SUSPEND_QP = 0x32, MLX4_CMD_UNSUSPEND_QP = 0x33, + MLX4_CMD_UPDATE_QP = 0x61, /* special QP and management commands */ MLX4_CMD_CONF_SPECIAL_QP = 0x23, MLX4_CMD_MAD_IFC = 0x24, @@ -232,6 +235,11 @@ struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev); void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox); u32 mlx4_comm_get_version(void); +int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac); +int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos); +int mlx4_set_vf_spoofchk(struct mlx4_dev *dev, int port, int vf, bool setting); +int mlx4_get_vf_config(struct mlx4_dev *dev, int port, int vf, struct ifla_vf_info *ivf); +int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_state); #define MLX4_COMM_GET_IF_REV(cmd_chan_ver) (u8)((cmd_chan_ver) >> 8) diff --git a/include/linux/mlx4/cq.h b/include/linux/mlx4/cq.h index 6f65b2c8bb89..98fa492cf406 100644 --- a/include/linux/mlx4/cq.h +++ b/include/linux/mlx4/cq.h @@ -64,6 +64,22 @@ struct mlx4_err_cqe { u8 owner_sr_opcode; }; +struct mlx4_ts_cqe { + __be32 vlan_my_qpn; + __be32 immed_rss_invalid; + __be32 g_mlpath_rqpn; + __be32 timestamp_hi; + __be16 status; + u8 ipv6_ext_mask; + u8 badfcs_enc; + __be32 byte_cnt; + __be16 wqe_index; + __be16 checksum; + u8 reserved; + __be16 timestamp_lo; + u8 owner_sr_opcode; +} __packed; + enum { MLX4_CQE_VLAN_PRESENT_MASK = 1 << 29, MLX4_CQE_QPN_MASK = 0xffffff, diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 811f91cf5e8c..24ce6bdd540e 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -33,6 +33,7 @@ #ifndef MLX4_DEVICE_H #define MLX4_DEVICE_H +#include <linux/if_ether.h> #include <linux/pci.h> #include <linux/completion.h> #include <linux/radix-tree.h> @@ -40,6 +41,8 @@ #include <linux/atomic.h> +#include <linux/clocksource.h> + #define MAX_MSIX_P_PORT 17 #define MAX_MSIX 64 #define MSIX_LEGACY_SZ 4 @@ -140,6 +143,7 @@ enum { MLX4_DEV_CAP_FLAG_VEP_UC_STEER = 1LL << 41, MLX4_DEV_CAP_FLAG_VEP_MC_STEER = 1LL << 42, MLX4_DEV_CAP_FLAG_COUNTERS = 1LL << 48, + MLX4_DEV_CAP_FLAG_SET_ETH_SCHED = 1LL << 53, MLX4_DEV_CAP_FLAG_SENSE_SUPPORT = 1LL << 55, MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV = 1LL << 59, MLX4_DEV_CAP_FLAG_64B_EQE = 1LL << 61, @@ -151,7 +155,11 @@ enum { MLX4_DEV_CAP_FLAG2_RSS_TOP = 1LL << 1, MLX4_DEV_CAP_FLAG2_RSS_XOR = 1LL << 2, MLX4_DEV_CAP_FLAG2_FS_EN = 1LL << 3, - MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN = 1LL << 4 + MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN = 1LL << 4, + MLX4_DEV_CAP_FLAG2_TS = 1LL << 5, + MLX4_DEV_CAP_FLAG2_VLAN_CONTROL = 1LL << 6, + MLX4_DEV_CAP_FLAG2_FSM = 1LL << 7, + MLX4_DEV_CAP_FLAG2_UPDATE_QP = 1LL << 8 }; enum { @@ -200,6 +208,7 @@ enum mlx4_event { MLX4_EVENT_TYPE_CMD = 0x0a, MLX4_EVENT_TYPE_VEP_UPDATE = 0x19, MLX4_EVENT_TYPE_COMM_CHANNEL = 0x18, + MLX4_EVENT_TYPE_OP_REQUIRED = 0x1a, MLX4_EVENT_TYPE_FATAL_WARNING = 0x1b, MLX4_EVENT_TYPE_FLR_EVENT = 0x1c, MLX4_EVENT_TYPE_PORT_MNG_CHG_EVENT = 0x1d, @@ -443,6 +452,7 @@ struct mlx4_caps { u8 eqe_factor; u32 userspace_caps; /* userspace must be aware of these */ u32 function_caps; /* VFs must be aware of these */ + u16 hca_core_clock; }; struct mlx4_buf_list { @@ -611,7 +621,7 @@ struct mlx4_eth_av { u8 dgid[16]; u32 reserved4[2]; __be16 vlan; - u8 mac[6]; + u8 mac[ETH_ALEN]; }; union mlx4_ext_av { @@ -837,7 +847,7 @@ void mlx4_free_hwq_res(struct mlx4_dev *mdev, struct mlx4_hwq_resources *wqres, int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt, struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq, - unsigned vector, int collapsed); + unsigned vector, int collapsed, int timestamp_en); void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq); int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base); @@ -896,18 +906,19 @@ static inline int map_hw_to_sw_id(u16 header_id) } enum mlx4_net_trans_promisc_mode { - MLX4_FS_PROMISC_NONE = 0, - MLX4_FS_PROMISC_UPLINK, - /* For future use. Not implemented yet */ - MLX4_FS_PROMISC_FUNCTION_PORT, - MLX4_FS_PROMISC_ALL_MULTI, + MLX4_FS_REGULAR = 1, + MLX4_FS_ALL_DEFAULT, + MLX4_FS_MC_DEFAULT, + MLX4_FS_UC_SNIFFER, + MLX4_FS_MC_SNIFFER, + MLX4_FS_MODE_NUM, /* should be last */ }; struct mlx4_spec_eth { - u8 dst_mac[6]; - u8 dst_mac_msk[6]; - u8 src_mac[6]; - u8 src_mac_msk[6]; + u8 dst_mac[ETH_ALEN]; + u8 dst_mac_msk[ETH_ALEN]; + u8 src_mac[ETH_ALEN]; + u8 src_mac_msk[ETH_ALEN]; u8 ether_type_enable; __be16 ether_type; __be16 vlan_id_msk; @@ -929,7 +940,7 @@ struct mlx4_spec_ipv4 { }; struct mlx4_spec_ib { - __be32 r_qpn; + __be32 l3_qpn; __be32 qpn_msk; u8 dst_gid[16]; u8 dst_gid_msk[16]; @@ -962,6 +973,87 @@ struct mlx4_net_trans_rule { u32 qpn; }; +struct mlx4_net_trans_rule_hw_ctrl { + __be16 prio; + u8 type; + u8 flags; + u8 rsvd1; + u8 funcid; + u8 vep; + u8 port; + __be32 qpn; + __be32 rsvd2; +}; + +struct mlx4_net_trans_rule_hw_ib { + u8 size; + u8 rsvd1; + __be16 id; + u32 rsvd2; + __be32 l3_qpn; + __be32 qpn_mask; + u8 dst_gid[16]; + u8 dst_gid_msk[16]; +} __packed; + +struct mlx4_net_trans_rule_hw_eth { + u8 size; + u8 rsvd; + __be16 id; + u8 rsvd1[6]; + u8 dst_mac[6]; + u16 rsvd2; + u8 dst_mac_msk[6]; + u16 rsvd3; + u8 src_mac[6]; + u16 rsvd4; + u8 src_mac_msk[6]; + u8 rsvd5; + u8 ether_type_enable; + __be16 ether_type; + __be16 vlan_tag_msk; + __be16 vlan_tag; +} __packed; + +struct mlx4_net_trans_rule_hw_tcp_udp { + u8 size; + u8 rsvd; + __be16 id; + __be16 rsvd1[3]; + __be16 dst_port; + __be16 rsvd2; + __be16 dst_port_msk; + __be16 rsvd3; + __be16 src_port; + __be16 rsvd4; + __be16 src_port_msk; +} __packed; + +struct mlx4_net_trans_rule_hw_ipv4 { + u8 size; + u8 rsvd; + __be16 id; + __be32 rsvd1; + __be32 dst_ip; + __be32 dst_ip_msk; + __be32 src_ip; + __be32 src_ip_msk; +} __packed; + +struct _rule_hw { + union { + struct { + u8 size; + u8 rsvd; + __be16 id; + }; + struct mlx4_net_trans_rule_hw_eth eth; + struct mlx4_net_trans_rule_hw_ib ib; + struct mlx4_net_trans_rule_hw_ipv4 ipv4; + struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; + }; +}; + int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port, u32 qpn, enum mlx4_net_trans_promisc_mode mode); int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port, @@ -1011,6 +1103,11 @@ void mlx4_counter_free(struct mlx4_dev *dev, u32 idx); int mlx4_flow_attach(struct mlx4_dev *dev, struct mlx4_net_trans_rule *rule, u64 *reg_id); int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id); +int mlx4_map_sw_to_hw_steering_mode(struct mlx4_dev *dev, + enum mlx4_net_trans_promisc_mode flow_type); +int mlx4_map_sw_to_hw_steering_id(struct mlx4_dev *dev, + enum mlx4_net_trans_rule_id id); +int mlx4_hw_rule_sz(struct mlx4_dev *dev, enum mlx4_net_trans_rule_id id); void mlx4_sync_pkey_table(struct mlx4_dev *dev, int slave, int port, int i, int val); @@ -1028,4 +1125,6 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave, u8 port, int void mlx4_put_slave_node_guid(struct mlx4_dev *dev, int slave, __be64 guid); __be64 mlx4_get_slave_node_guid(struct mlx4_dev *dev, int slave); +cycle_t mlx4_read_clock(struct mlx4_dev *dev); + #endif /* MLX4_DEVICE_H */ diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h index 67f46ad6920a..6d351473c292 100644 --- a/include/linux/mlx4/qp.h +++ b/include/linux/mlx4/qp.h @@ -34,6 +34,7 @@ #define MLX4_QP_H #include <linux/types.h> +#include <linux/if_ether.h> #include <linux/mlx4/device.h> @@ -126,7 +127,7 @@ struct mlx4_rss_context { struct mlx4_qp_path { u8 fl; - u8 reserved1[1]; + u8 vlan_control; u8 disable_pkey_check; u8 pkey_index; u8 counter_index; @@ -141,9 +142,32 @@ struct mlx4_qp_path { u8 sched_queue; u8 vlan_index; u8 feup; - u8 reserved3; + u8 fvl_rx; u8 reserved4[2]; - u8 dmac[6]; + u8 dmac[ETH_ALEN]; +}; + +enum { /* fl */ + MLX4_FL_CV = 1 << 6, + MLX4_FL_ETH_HIDE_CQE_VLAN = 1 << 2 +}; +enum { /* vlan_control */ + MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED = 1 << 6, + MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED = 1 << 5, /* 802.1p priority tag */ + MLX4_VLAN_CTRL_ETH_TX_BLOCK_UNTAGGED = 1 << 4, + MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED = 1 << 2, + MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED = 1 << 1, /* 802.1p priority tag */ + MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED = 1 << 0 +}; + +enum { /* feup */ + MLX4_FEUP_FORCE_ETH_UP = 1 << 6, /* force Eth UP */ + MLX4_FSM_FORCE_ETH_SRC_MAC = 1 << 5, /* force Source MAC */ + MLX4_FVL_FORCE_ETH_VLAN = 1 << 3 /* force Eth vlan */ +}; + +enum { /* fvl_rx */ + MLX4_FVL_RX_FORCE_ETH_VLAN = 1 << 0 /* enforce Eth rx vlan */ }; struct mlx4_qp_context { @@ -185,6 +209,44 @@ struct mlx4_qp_context { u32 reserved5[10]; }; +struct mlx4_update_qp_context { + __be64 qp_mask; + __be64 primary_addr_path_mask; + __be64 secondary_addr_path_mask; + u64 reserved1; + struct mlx4_qp_context qp_context; + u64 reserved2[58]; +}; + +enum { + MLX4_UPD_QP_MASK_PM_STATE = 32, + MLX4_UPD_QP_MASK_VSD = 33, +}; + +enum { + MLX4_UPD_QP_PATH_MASK_PKEY_INDEX = 0 + 32, + MLX4_UPD_QP_PATH_MASK_FSM = 1 + 32, + MLX4_UPD_QP_PATH_MASK_MAC_INDEX = 2 + 32, + MLX4_UPD_QP_PATH_MASK_FVL = 3 + 32, + MLX4_UPD_QP_PATH_MASK_CV = 4 + 32, + MLX4_UPD_QP_PATH_MASK_VLAN_INDEX = 5 + 32, + MLX4_UPD_QP_PATH_MASK_ETH_HIDE_CQE_VLAN = 6 + 32, + MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_UNTAGGED = 7 + 32, + MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_1P = 8 + 32, + MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_TAGGED = 9 + 32, + MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_UNTAGGED = 10 + 32, + MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_1P = 11 + 32, + MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_TAGGED = 12 + 32, + MLX4_UPD_QP_PATH_MASK_FEUP = 13 + 32, + MLX4_UPD_QP_PATH_MASK_SCHED_QUEUE = 14 + 32, + MLX4_UPD_QP_PATH_MASK_IF_COUNTER_INDEX = 15 + 32, + MLX4_UPD_QP_PATH_MASK_FVL_RX = 16 + 32, +}; + +enum { /* param3 */ + MLX4_STRIP_VLAN = 1 << 30 +}; + /* Which firmware version adds support for NEC (NoErrorCompletion) bit */ #define MLX4_FW_VER_WQE_CTRL_NEC mlx4_fw_ver(2, 2, 232) @@ -257,7 +319,7 @@ struct mlx4_wqe_datagram_seg { __be32 dqpn; __be32 qkey; __be16 vlan; - u8 mac[6]; + u8 mac[ETH_ALEN]; }; struct mlx4_wqe_lso_seg { diff --git a/include/linux/mlx4/srq.h b/include/linux/mlx4/srq.h index 799a0697a383..192e0f7784f2 100644 --- a/include/linux/mlx4/srq.h +++ b/include/linux/mlx4/srq.h @@ -39,4 +39,6 @@ struct mlx4_wqe_srq_next_seg { u32 reserved2[3]; }; +struct mlx4_srq *mlx4_srq_lookup(struct mlx4_dev *dev, u32 srqn); + #endif /* MLX4_SRQ_H */ diff --git a/include/linux/mlx5/cmd.h b/include/linux/mlx5/cmd.h new file mode 100644 index 000000000000..2826a4b6071e --- /dev/null +++ b/include/linux/mlx5/cmd.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013, Mellanox Technologies inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MLX5_CMD_H +#define MLX5_CMD_H + +#include <linux/types.h> + +struct manage_pages_layout { + u64 ptr; + u32 reserved; + u16 num_entries; + u16 func_id; +}; + + +struct mlx5_cmd_alloc_uar_imm_out { + u32 rsvd[3]; + u32 uarn; +}; + +#endif /* MLX5_CMD_H */ diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h new file mode 100644 index 000000000000..3db67f73d96d --- /dev/null +++ b/include/linux/mlx5/cq.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2013, Mellanox Technologies inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MLX5_CORE_CQ_H +#define MLX5_CORE_CQ_H + +#include <rdma/ib_verbs.h> +#include <linux/mlx5/driver.h> + + +struct mlx5_core_cq { + u32 cqn; + int cqe_sz; + __be32 *set_ci_db; + __be32 *arm_db; + atomic_t refcount; + struct completion free; + unsigned vector; + int irqn; + void (*comp) (struct mlx5_core_cq *); + void (*event) (struct mlx5_core_cq *, enum mlx5_event); + struct mlx5_uar *uar; + u32 cons_index; + unsigned arm_sn; + struct mlx5_rsc_debug *dbg; + int pid; +}; + + +enum { + MLX5_CQE_SYNDROME_LOCAL_LENGTH_ERR = 0x01, + MLX5_CQE_SYNDROME_LOCAL_QP_OP_ERR = 0x02, + MLX5_CQE_SYNDROME_LOCAL_PROT_ERR = 0x04, + MLX5_CQE_SYNDROME_WR_FLUSH_ERR = 0x05, + MLX5_CQE_SYNDROME_MW_BIND_ERR = 0x06, + MLX5_CQE_SYNDROME_BAD_RESP_ERR = 0x10, + MLX5_CQE_SYNDROME_LOCAL_ACCESS_ERR = 0x11, + MLX5_CQE_SYNDROME_REMOTE_INVAL_REQ_ERR = 0x12, + MLX5_CQE_SYNDROME_REMOTE_ACCESS_ERR = 0x13, + MLX5_CQE_SYNDROME_REMOTE_OP_ERR = 0x14, + MLX5_CQE_SYNDROME_TRANSPORT_RETRY_EXC_ERR = 0x15, + MLX5_CQE_SYNDROME_RNR_RETRY_EXC_ERR = 0x16, + MLX5_CQE_SYNDROME_REMOTE_ABORTED_ERR = 0x22, +}; + +enum { + MLX5_CQE_OWNER_MASK = 1, + MLX5_CQE_REQ = 0, + MLX5_CQE_RESP_WR_IMM = 1, + MLX5_CQE_RESP_SEND = 2, + MLX5_CQE_RESP_SEND_IMM = 3, + MLX5_CQE_RESP_SEND_INV = 4, + MLX5_CQE_RESIZE_CQ = 0xff, /* TBD */ + MLX5_CQE_REQ_ERR = 13, + MLX5_CQE_RESP_ERR = 14, +}; + +enum { + MLX5_CQ_MODIFY_RESEIZE = 0, + MLX5_CQ_MODIFY_MODER = 1, + MLX5_CQ_MODIFY_MAPPING = 2, +}; + +struct mlx5_cq_modify_params { + int type; + union { + struct { + u32 page_offset; + u8 log_cq_size; + } resize; + + struct { + } moder; + + struct { + } mapping; + } params; +}; + +enum { + CQE_SIZE_64 = 0, + CQE_SIZE_128 = 1, +}; + +static inline int cqe_sz_to_mlx_sz(u8 size) +{ + return size == 64 ? CQE_SIZE_64 : CQE_SIZE_128; +} + +static inline void mlx5_cq_set_ci(struct mlx5_core_cq *cq) +{ + *cq->set_ci_db = cpu_to_be32(cq->cons_index & 0xffffff); +} + +enum { + MLX5_CQ_DB_REQ_NOT_SOL = 1 << 24, + MLX5_CQ_DB_REQ_NOT = 0 << 24 +}; + +static inline void mlx5_cq_arm(struct mlx5_core_cq *cq, u32 cmd, + void __iomem *uar_page, + spinlock_t *doorbell_lock) +{ + __be32 doorbell[2]; + u32 sn; + u32 ci; + + sn = cq->arm_sn & 3; + ci = cq->cons_index & 0xffffff; + + *cq->arm_db = cpu_to_be32(sn << 28 | cmd | ci); + + /* Make sure that the doorbell record in host memory is + * written before ringing the doorbell via PCI MMIO. + */ + wmb(); + + doorbell[0] = cpu_to_be32(sn << 28 | cmd | ci); + doorbell[1] = cpu_to_be32(cq->cqn); + + mlx5_write64(doorbell, uar_page + MLX5_CQ_DOORBELL, doorbell_lock); +} + +int mlx5_init_cq_table(struct mlx5_core_dev *dev); +void mlx5_cleanup_cq_table(struct mlx5_core_dev *dev); +int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, + struct mlx5_create_cq_mbox_in *in, int inlen); +int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq); +int mlx5_core_query_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, + struct mlx5_query_cq_mbox_out *out); +int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, + int type, struct mlx5_cq_modify_params *params); +int mlx5_debug_cq_add(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq); +void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq); + +#endif /* MLX5_CORE_CQ_H */ diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h new file mode 100644 index 000000000000..68029b30c3dc --- /dev/null +++ b/include/linux/mlx5/device.h @@ -0,0 +1,911 @@ +/* + * Copyright (c) 2013, Mellanox Technologies inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MLX5_DEVICE_H +#define MLX5_DEVICE_H + +#include <linux/types.h> +#include <rdma/ib_verbs.h> + +#if defined(__LITTLE_ENDIAN) +#define MLX5_SET_HOST_ENDIANNESS 0 +#elif defined(__BIG_ENDIAN) +#define MLX5_SET_HOST_ENDIANNESS 0x80 +#else +#error Host endianness not defined +#endif + +enum { + MLX5_MAX_COMMANDS = 32, + MLX5_CMD_DATA_BLOCK_SIZE = 512, + MLX5_PCI_CMD_XPORT = 7, +}; + +enum { + MLX5_EXTENDED_UD_AV = 0x80000000, +}; + +enum { + MLX5_CQ_STATE_ARMED = 9, + MLX5_CQ_STATE_ALWAYS_ARMED = 0xb, + MLX5_CQ_STATE_FIRED = 0xa, +}; + +enum { + MLX5_STAT_RATE_OFFSET = 5, +}; + +enum { + MLX5_INLINE_SEG = 0x80000000, +}; + +enum { + MLX5_PERM_LOCAL_READ = 1 << 2, + MLX5_PERM_LOCAL_WRITE = 1 << 3, + MLX5_PERM_REMOTE_READ = 1 << 4, + MLX5_PERM_REMOTE_WRITE = 1 << 5, + MLX5_PERM_ATOMIC = 1 << 6, + MLX5_PERM_UMR_EN = 1 << 7, +}; + +enum { + MLX5_PCIE_CTRL_SMALL_FENCE = 1 << 0, + MLX5_PCIE_CTRL_RELAXED_ORDERING = 1 << 2, + MLX5_PCIE_CTRL_NO_SNOOP = 1 << 3, + MLX5_PCIE_CTRL_TLP_PROCE_EN = 1 << 6, + MLX5_PCIE_CTRL_TPH_MASK = 3 << 4, +}; + +enum { + MLX5_ACCESS_MODE_PA = 0, + MLX5_ACCESS_MODE_MTT = 1, + MLX5_ACCESS_MODE_KLM = 2 +}; + +enum { + MLX5_MKEY_REMOTE_INVAL = 1 << 24, + MLX5_MKEY_FLAG_SYNC_UMR = 1 << 29, + MLX5_MKEY_BSF_EN = 1 << 30, + MLX5_MKEY_LEN64 = 1 << 31, +}; + +enum { + MLX5_EN_RD = (u64)1, + MLX5_EN_WR = (u64)2 +}; + +enum { + MLX5_BF_REGS_PER_PAGE = 4, + MLX5_MAX_UAR_PAGES = 1 << 8, + MLX5_MAX_UUARS = MLX5_MAX_UAR_PAGES * MLX5_BF_REGS_PER_PAGE, +}; + +enum { + MLX5_MKEY_MASK_LEN = 1ull << 0, + MLX5_MKEY_MASK_PAGE_SIZE = 1ull << 1, + MLX5_MKEY_MASK_START_ADDR = 1ull << 6, + MLX5_MKEY_MASK_PD = 1ull << 7, + MLX5_MKEY_MASK_EN_RINVAL = 1ull << 8, + MLX5_MKEY_MASK_BSF_EN = 1ull << 12, + MLX5_MKEY_MASK_KEY = 1ull << 13, + MLX5_MKEY_MASK_QPN = 1ull << 14, + MLX5_MKEY_MASK_LR = 1ull << 17, + MLX5_MKEY_MASK_LW = 1ull << 18, + MLX5_MKEY_MASK_RR = 1ull << 19, + MLX5_MKEY_MASK_RW = 1ull << 20, + MLX5_MKEY_MASK_A = 1ull << 21, + MLX5_MKEY_MASK_SMALL_FENCE = 1ull << 23, + MLX5_MKEY_MASK_FREE = 1ull << 29, +}; + +enum mlx5_event { + MLX5_EVENT_TYPE_COMP = 0x0, + + MLX5_EVENT_TYPE_PATH_MIG = 0x01, + MLX5_EVENT_TYPE_COMM_EST = 0x02, + MLX5_EVENT_TYPE_SQ_DRAINED = 0x03, + MLX5_EVENT_TYPE_SRQ_LAST_WQE = 0x13, + MLX5_EVENT_TYPE_SRQ_RQ_LIMIT = 0x14, + + MLX5_EVENT_TYPE_CQ_ERROR = 0x04, + MLX5_EVENT_TYPE_WQ_CATAS_ERROR = 0x05, + MLX5_EVENT_TYPE_PATH_MIG_FAILED = 0x07, + MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR = 0x10, + MLX5_EVENT_TYPE_WQ_ACCESS_ERROR = 0x11, + MLX5_EVENT_TYPE_SRQ_CATAS_ERROR = 0x12, + + MLX5_EVENT_TYPE_INTERNAL_ERROR = 0x08, + MLX5_EVENT_TYPE_PORT_CHANGE = 0x09, + MLX5_EVENT_TYPE_GPIO_EVENT = 0x15, + MLX5_EVENT_TYPE_REMOTE_CONFIG = 0x19, + + MLX5_EVENT_TYPE_DB_BF_CONGESTION = 0x1a, + MLX5_EVENT_TYPE_STALL_EVENT = 0x1b, + + MLX5_EVENT_TYPE_CMD = 0x0a, + MLX5_EVENT_TYPE_PAGE_REQUEST = 0xb, +}; + +enum { + MLX5_PORT_CHANGE_SUBTYPE_DOWN = 1, + MLX5_PORT_CHANGE_SUBTYPE_ACTIVE = 4, + MLX5_PORT_CHANGE_SUBTYPE_INITIALIZED = 5, + MLX5_PORT_CHANGE_SUBTYPE_LID = 6, + MLX5_PORT_CHANGE_SUBTYPE_PKEY = 7, + MLX5_PORT_CHANGE_SUBTYPE_GUID = 8, + MLX5_PORT_CHANGE_SUBTYPE_CLIENT_REREG = 9, +}; + +enum { + MLX5_DEV_CAP_FLAG_RC = 1LL << 0, + MLX5_DEV_CAP_FLAG_UC = 1LL << 1, + MLX5_DEV_CAP_FLAG_UD = 1LL << 2, + MLX5_DEV_CAP_FLAG_XRC = 1LL << 3, + MLX5_DEV_CAP_FLAG_SRQ = 1LL << 6, + MLX5_DEV_CAP_FLAG_BAD_PKEY_CNTR = 1LL << 8, + MLX5_DEV_CAP_FLAG_BAD_QKEY_CNTR = 1LL << 9, + MLX5_DEV_CAP_FLAG_APM = 1LL << 17, + MLX5_DEV_CAP_FLAG_ATOMIC = 1LL << 18, + MLX5_DEV_CAP_FLAG_ON_DMND_PG = 1LL << 24, + MLX5_DEV_CAP_FLAG_RESIZE_SRQ = 1LL << 32, + MLX5_DEV_CAP_FLAG_REMOTE_FENCE = 1LL << 38, + MLX5_DEV_CAP_FLAG_TLP_HINTS = 1LL << 39, + MLX5_DEV_CAP_FLAG_SIG_HAND_OVER = 1LL << 40, + MLX5_DEV_CAP_FLAG_DCT = 1LL << 41, + MLX5_DEV_CAP_FLAG_CMDIF_CSUM = 1LL << 46, +}; + +enum { + MLX5_OPCODE_NOP = 0x00, + MLX5_OPCODE_SEND_INVAL = 0x01, + MLX5_OPCODE_RDMA_WRITE = 0x08, + MLX5_OPCODE_RDMA_WRITE_IMM = 0x09, + MLX5_OPCODE_SEND = 0x0a, + MLX5_OPCODE_SEND_IMM = 0x0b, + MLX5_OPCODE_RDMA_READ = 0x10, + MLX5_OPCODE_ATOMIC_CS = 0x11, + MLX5_OPCODE_ATOMIC_FA = 0x12, + MLX5_OPCODE_ATOMIC_MASKED_CS = 0x14, + MLX5_OPCODE_ATOMIC_MASKED_FA = 0x15, + MLX5_OPCODE_BIND_MW = 0x18, + MLX5_OPCODE_CONFIG_CMD = 0x1f, + + MLX5_RECV_OPCODE_RDMA_WRITE_IMM = 0x00, + MLX5_RECV_OPCODE_SEND = 0x01, + MLX5_RECV_OPCODE_SEND_IMM = 0x02, + MLX5_RECV_OPCODE_SEND_INVAL = 0x03, + + MLX5_CQE_OPCODE_ERROR = 0x1e, + MLX5_CQE_OPCODE_RESIZE = 0x16, + + MLX5_OPCODE_SET_PSV = 0x20, + MLX5_OPCODE_GET_PSV = 0x21, + MLX5_OPCODE_CHECK_PSV = 0x22, + MLX5_OPCODE_RGET_PSV = 0x26, + MLX5_OPCODE_RCHECK_PSV = 0x27, + + MLX5_OPCODE_UMR = 0x25, + +}; + +enum { + MLX5_SET_PORT_RESET_QKEY = 0, + MLX5_SET_PORT_GUID0 = 16, + MLX5_SET_PORT_NODE_GUID = 17, + MLX5_SET_PORT_SYS_GUID = 18, + MLX5_SET_PORT_GID_TABLE = 19, + MLX5_SET_PORT_PKEY_TABLE = 20, +}; + +enum { + MLX5_MAX_PAGE_SHIFT = 31 +}; + +struct mlx5_inbox_hdr { + __be16 opcode; + u8 rsvd[4]; + __be16 opmod; +}; + +struct mlx5_outbox_hdr { + u8 status; + u8 rsvd[3]; + __be32 syndrome; +}; + +struct mlx5_cmd_query_adapter_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_cmd_query_adapter_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd0[24]; + u8 intapin; + u8 rsvd1[13]; + __be16 vsd_vendor_id; + u8 vsd[208]; + u8 vsd_psid[16]; +}; + +struct mlx5_hca_cap { + u8 rsvd1[16]; + u8 log_max_srq_sz; + u8 log_max_qp_sz; + u8 rsvd2; + u8 log_max_qp; + u8 log_max_strq_sz; + u8 log_max_srqs; + u8 rsvd4[2]; + u8 rsvd5; + u8 log_max_cq_sz; + u8 rsvd6; + u8 log_max_cq; + u8 log_max_eq_sz; + u8 log_max_mkey; + u8 rsvd7; + u8 log_max_eq; + u8 max_indirection; + u8 log_max_mrw_sz; + u8 log_max_bsf_list_sz; + u8 log_max_klm_list_sz; + u8 rsvd_8_0; + u8 log_max_ra_req_dc; + u8 rsvd_8_1; + u8 log_max_ra_res_dc; + u8 rsvd9; + u8 log_max_ra_req_qp; + u8 rsvd10; + u8 log_max_ra_res_qp; + u8 rsvd11[4]; + __be16 max_qp_count; + __be16 rsvd12; + u8 rsvd13; + u8 local_ca_ack_delay; + u8 rsvd14; + u8 num_ports; + u8 log_max_msg; + u8 rsvd15[3]; + __be16 stat_rate_support; + u8 rsvd16[2]; + __be64 flags; + u8 rsvd17; + u8 uar_sz; + u8 rsvd18; + u8 log_pg_sz; + __be16 bf_log_bf_reg_size; + u8 rsvd19[4]; + __be16 max_desc_sz_sq; + u8 rsvd20[2]; + __be16 max_desc_sz_rq; + u8 rsvd21[2]; + __be16 max_desc_sz_sq_dc; + __be32 max_qp_mcg; + u8 rsvd22[3]; + u8 log_max_mcg; + u8 rsvd23; + u8 log_max_pd; + u8 rsvd24; + u8 log_max_xrcd; + u8 rsvd25[42]; + __be16 log_uar_page_sz; + u8 rsvd26[28]; + u8 log_msx_atomic_size_qp; + u8 rsvd27[2]; + u8 log_msx_atomic_size_dc; + u8 rsvd28[76]; +}; + + +struct mlx5_cmd_query_hca_cap_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd[8]; +}; + + +struct mlx5_cmd_query_hca_cap_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd0[8]; + struct mlx5_hca_cap hca_cap; +}; + + +struct mlx5_cmd_set_hca_cap_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd[8]; + struct mlx5_hca_cap hca_cap; +}; + + +struct mlx5_cmd_set_hca_cap_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd0[8]; +}; + + +struct mlx5_cmd_init_hca_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd0[2]; + __be16 profile; + u8 rsvd1[4]; +}; + +struct mlx5_cmd_init_hca_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_cmd_teardown_hca_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd0[2]; + __be16 profile; + u8 rsvd1[4]; +}; + +struct mlx5_cmd_teardown_hca_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_cmd_layout { + u8 type; + u8 rsvd0[3]; + __be32 inlen; + __be64 in_ptr; + __be32 in[4]; + __be32 out[4]; + __be64 out_ptr; + __be32 outlen; + u8 token; + u8 sig; + u8 rsvd1; + u8 status_own; +}; + + +struct health_buffer { + __be32 assert_var[5]; + __be32 rsvd0[3]; + __be32 assert_exit_ptr; + __be32 assert_callra; + __be32 rsvd1[2]; + __be32 fw_ver; + __be32 hw_id; + __be32 rsvd2; + u8 irisc_index; + u8 synd; + __be16 ext_sync; +}; + +struct mlx5_init_seg { + __be32 fw_rev; + __be32 cmdif_rev_fw_sub; + __be32 rsvd0[2]; + __be32 cmdq_addr_h; + __be32 cmdq_addr_l_sz; + __be32 cmd_dbell; + __be32 rsvd1[121]; + struct health_buffer health; + __be32 rsvd2[884]; + __be32 health_counter; + __be32 rsvd3[1023]; + __be64 ieee1588_clk; + __be32 ieee1588_clk_type; + __be32 clr_intx; +}; + +struct mlx5_eqe_comp { + __be32 reserved[6]; + __be32 cqn; +}; + +struct mlx5_eqe_qp_srq { + __be32 reserved[6]; + __be32 qp_srq_n; +}; + +struct mlx5_eqe_cq_err { + __be32 cqn; + u8 reserved1[7]; + u8 syndrome; +}; + +struct mlx5_eqe_dropped_packet { +}; + +struct mlx5_eqe_port_state { + u8 reserved0[8]; + u8 port; +}; + +struct mlx5_eqe_gpio { + __be32 reserved0[2]; + __be64 gpio_event; +}; + +struct mlx5_eqe_congestion { + u8 type; + u8 rsvd0; + u8 congestion_level; +}; + +struct mlx5_eqe_stall_vl { + u8 rsvd0[3]; + u8 port_vl; +}; + +struct mlx5_eqe_cmd { + __be32 vector; + __be32 rsvd[6]; +}; + +struct mlx5_eqe_page_req { + u8 rsvd0[2]; + __be16 func_id; + __be32 num_pages; + __be32 rsvd1[5]; +}; + +union ev_data { + __be32 raw[7]; + struct mlx5_eqe_cmd cmd; + struct mlx5_eqe_comp comp; + struct mlx5_eqe_qp_srq qp_srq; + struct mlx5_eqe_cq_err cq_err; + struct mlx5_eqe_dropped_packet dp; + struct mlx5_eqe_port_state port; + struct mlx5_eqe_gpio gpio; + struct mlx5_eqe_congestion cong; + struct mlx5_eqe_stall_vl stall_vl; + struct mlx5_eqe_page_req req_pages; +} __packed; + +struct mlx5_eqe { + u8 rsvd0; + u8 type; + u8 rsvd1; + u8 sub_type; + __be32 rsvd2[7]; + union ev_data data; + __be16 rsvd3; + u8 signature; + u8 owner; +} __packed; + +struct mlx5_cmd_prot_block { + u8 data[MLX5_CMD_DATA_BLOCK_SIZE]; + u8 rsvd0[48]; + __be64 next; + __be32 block_num; + u8 rsvd1; + u8 token; + u8 ctrl_sig; + u8 sig; +}; + +struct mlx5_err_cqe { + u8 rsvd0[32]; + __be32 srqn; + u8 rsvd1[18]; + u8 vendor_err_synd; + u8 syndrome; + __be32 s_wqe_opcode_qpn; + __be16 wqe_counter; + u8 signature; + u8 op_own; +}; + +struct mlx5_cqe64 { + u8 rsvd0[17]; + u8 ml_path; + u8 rsvd20[4]; + __be16 slid; + __be32 flags_rqpn; + u8 rsvd28[4]; + __be32 srqn; + __be32 imm_inval_pkey; + u8 rsvd40[4]; + __be32 byte_cnt; + __be64 timestamp; + __be32 sop_drop_qpn; + __be16 wqe_counter; + u8 signature; + u8 op_own; +}; + +struct mlx5_wqe_srq_next_seg { + u8 rsvd0[2]; + __be16 next_wqe_index; + u8 signature; + u8 rsvd1[11]; +}; + +union mlx5_ext_cqe { + struct ib_grh grh; + u8 inl[64]; +}; + +struct mlx5_cqe128 { + union mlx5_ext_cqe inl_grh; + struct mlx5_cqe64 cqe64; +}; + +struct mlx5_srq_ctx { + u8 state_log_sz; + u8 rsvd0[3]; + __be32 flags_xrcd; + __be32 pgoff_cqn; + u8 rsvd1[4]; + u8 log_pg_sz; + u8 rsvd2[7]; + __be32 pd; + __be16 lwm; + __be16 wqe_cnt; + u8 rsvd3[8]; + __be64 db_record; +}; + +struct mlx5_create_srq_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 input_srqn; + u8 rsvd0[4]; + struct mlx5_srq_ctx ctx; + u8 rsvd1[208]; + __be64 pas[0]; +}; + +struct mlx5_create_srq_mbox_out { + struct mlx5_outbox_hdr hdr; + __be32 srqn; + u8 rsvd[4]; +}; + +struct mlx5_destroy_srq_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 srqn; + u8 rsvd[4]; +}; + +struct mlx5_destroy_srq_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_query_srq_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 srqn; + u8 rsvd0[4]; +}; + +struct mlx5_query_srq_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd0[8]; + struct mlx5_srq_ctx ctx; + u8 rsvd1[32]; + __be64 pas[0]; +}; + +struct mlx5_arm_srq_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 srqn; + __be16 rsvd; + __be16 lwm; +}; + +struct mlx5_arm_srq_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_cq_context { + u8 status; + u8 cqe_sz_flags; + u8 st; + u8 rsvd3; + u8 rsvd4[6]; + __be16 page_offset; + __be32 log_sz_usr_page; + __be16 cq_period; + __be16 cq_max_count; + __be16 rsvd20; + __be16 c_eqn; + u8 log_pg_sz; + u8 rsvd25[7]; + __be32 last_notified_index; + __be32 solicit_producer_index; + __be32 consumer_counter; + __be32 producer_counter; + u8 rsvd48[8]; + __be64 db_record_addr; +}; + +struct mlx5_create_cq_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 input_cqn; + u8 rsvdx[4]; + struct mlx5_cq_context ctx; + u8 rsvd6[192]; + __be64 pas[0]; +}; + +struct mlx5_create_cq_mbox_out { + struct mlx5_outbox_hdr hdr; + __be32 cqn; + u8 rsvd0[4]; +}; + +struct mlx5_destroy_cq_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 cqn; + u8 rsvd0[4]; +}; + +struct mlx5_destroy_cq_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd0[8]; +}; + +struct mlx5_query_cq_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 cqn; + u8 rsvd0[4]; +}; + +struct mlx5_query_cq_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd0[8]; + struct mlx5_cq_context ctx; + u8 rsvd6[16]; + __be64 pas[0]; +}; + +struct mlx5_enable_hca_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_enable_hca_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_disable_hca_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_disable_hca_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_eq_context { + u8 status; + u8 ec_oi; + u8 st; + u8 rsvd2[7]; + __be16 page_pffset; + __be32 log_sz_usr_page; + u8 rsvd3[7]; + u8 intr; + u8 log_page_size; + u8 rsvd4[15]; + __be32 consumer_counter; + __be32 produser_counter; + u8 rsvd5[16]; +}; + +struct mlx5_create_eq_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd0[3]; + u8 input_eqn; + u8 rsvd1[4]; + struct mlx5_eq_context ctx; + u8 rsvd2[8]; + __be64 events_mask; + u8 rsvd3[176]; + __be64 pas[0]; +}; + +struct mlx5_create_eq_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd0[3]; + u8 eq_number; + u8 rsvd1[4]; +}; + +struct mlx5_destroy_eq_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd0[3]; + u8 eqn; + u8 rsvd1[4]; +}; + +struct mlx5_destroy_eq_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_map_eq_mbox_in { + struct mlx5_inbox_hdr hdr; + __be64 mask; + u8 mu; + u8 rsvd0[2]; + u8 eqn; + u8 rsvd1[24]; +}; + +struct mlx5_map_eq_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_query_eq_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd0[3]; + u8 eqn; + u8 rsvd1[4]; +}; + +struct mlx5_query_eq_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; + struct mlx5_eq_context ctx; +}; + +struct mlx5_mkey_seg { + /* This is a two bit field occupying bits 31-30. + * bit 31 is always 0, + * bit 30 is zero for regular MRs and 1 (e.g free) for UMRs that do not have tanslation + */ + u8 status; + u8 pcie_control; + u8 flags; + u8 version; + __be32 qpn_mkey7_0; + u8 rsvd1[4]; + __be32 flags_pd; + __be64 start_addr; + __be64 len; + __be32 bsfs_octo_size; + u8 rsvd2[16]; + __be32 xlt_oct_size; + u8 rsvd3[3]; + u8 log2_page_size; + u8 rsvd4[4]; +}; + +struct mlx5_query_special_ctxs_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_query_special_ctxs_mbox_out { + struct mlx5_outbox_hdr hdr; + __be32 dump_fill_mkey; + __be32 reserved_lkey; +}; + +struct mlx5_create_mkey_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 input_mkey_index; + u8 rsvd0[4]; + struct mlx5_mkey_seg seg; + u8 rsvd1[16]; + __be32 xlat_oct_act_size; + __be32 bsf_coto_act_size; + u8 rsvd2[168]; + __be64 pas[0]; +}; + +struct mlx5_create_mkey_mbox_out { + struct mlx5_outbox_hdr hdr; + __be32 mkey; + u8 rsvd[4]; +}; + +struct mlx5_destroy_mkey_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 mkey; + u8 rsvd[4]; +}; + +struct mlx5_destroy_mkey_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_query_mkey_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 mkey; +}; + +struct mlx5_query_mkey_mbox_out { + struct mlx5_outbox_hdr hdr; + __be64 pas[0]; +}; + +struct mlx5_modify_mkey_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 mkey; + __be64 pas[0]; +}; + +struct mlx5_modify_mkey_mbox_out { + struct mlx5_outbox_hdr hdr; +}; + +struct mlx5_dump_mkey_mbox_in { + struct mlx5_inbox_hdr hdr; +}; + +struct mlx5_dump_mkey_mbox_out { + struct mlx5_outbox_hdr hdr; + __be32 mkey; +}; + +struct mlx5_mad_ifc_mbox_in { + struct mlx5_inbox_hdr hdr; + __be16 remote_lid; + u8 rsvd0; + u8 port; + u8 rsvd1[4]; + u8 data[256]; +}; + +struct mlx5_mad_ifc_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; + u8 data[256]; +}; + +struct mlx5_access_reg_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd0[2]; + __be16 register_id; + __be32 arg; + __be32 data[0]; +}; + +struct mlx5_access_reg_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; + __be32 data[0]; +}; + +#define MLX5_ATTR_EXTENDED_PORT_INFO cpu_to_be16(0xff90) + +enum { + MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO = 1 << 0 +}; + +#endif /* MLX5_DEVICE_H */ diff --git a/include/linux/mlx5/doorbell.h b/include/linux/mlx5/doorbell.h new file mode 100644 index 000000000000..163a818411e7 --- /dev/null +++ b/include/linux/mlx5/doorbell.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, Mellanox Technologies inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MLX5_DOORBELL_H +#define MLX5_DOORBELL_H + +#define MLX5_BF_OFFSET 0x800 +#define MLX5_CQ_DOORBELL 0x20 + +#if BITS_PER_LONG == 64 +/* Assume that we can just write a 64-bit doorbell atomically. s390 + * actually doesn't have writeq() but S/390 systems don't even have + * PCI so we won't worry about it. + */ + +#define MLX5_DECLARE_DOORBELL_LOCK(name) +#define MLX5_INIT_DOORBELL_LOCK(ptr) do { } while (0) +#define MLX5_GET_DOORBELL_LOCK(ptr) (NULL) + +static inline void mlx5_write64(__be32 val[2], void __iomem *dest, + spinlock_t *doorbell_lock) +{ + __raw_writeq(*(u64 *)val, dest); +} + +#else + +/* Just fall back to a spinlock to protect the doorbell if + * BITS_PER_LONG is 32 -- there's no portable way to do atomic 64-bit + * MMIO writes. + */ + +#define MLX5_DECLARE_DOORBELL_LOCK(name) spinlock_t name; +#define MLX5_INIT_DOORBELL_LOCK(ptr) spin_lock_init(ptr) +#define MLX5_GET_DOORBELL_LOCK(ptr) (ptr) + +static inline void mlx5_write64(__be32 val[2], void __iomem *dest, + spinlock_t *doorbell_lock) +{ + unsigned long flags; + + spin_lock_irqsave(doorbell_lock, flags); + __raw_writel((__force u32) val[0], dest); + __raw_writel((__force u32) val[1], dest + 4); + spin_unlock_irqrestore(doorbell_lock, flags); +} + +#endif + +#endif /* MLX5_DOORBELL_H */ diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h new file mode 100644 index 000000000000..8888381fc150 --- /dev/null +++ b/include/linux/mlx5/driver.h @@ -0,0 +1,768 @@ +/* + * Copyright (c) 2013, Mellanox Technologies inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MLX5_DRIVER_H +#define MLX5_DRIVER_H + +#include <linux/kernel.h> +#include <linux/completion.h> +#include <linux/pci.h> +#include <linux/spinlock_types.h> +#include <linux/semaphore.h> +#include <linux/vmalloc.h> +#include <linux/radix-tree.h> +#include <linux/mlx5/device.h> +#include <linux/mlx5/doorbell.h> + +enum { + MLX5_BOARD_ID_LEN = 64, + MLX5_MAX_NAME_LEN = 16, +}; + +enum { + /* one minute for the sake of bringup. Generally, commands must always + * complete and we may need to increase this timeout value + */ + MLX5_CMD_TIMEOUT_MSEC = 7200 * 1000, + MLX5_CMD_WQ_MAX_NAME = 32, +}; + +enum { + CMD_OWNER_SW = 0x0, + CMD_OWNER_HW = 0x1, + CMD_STATUS_SUCCESS = 0, +}; + +enum mlx5_sqp_t { + MLX5_SQP_SMI = 0, + MLX5_SQP_GSI = 1, + MLX5_SQP_IEEE_1588 = 2, + MLX5_SQP_SNIFFER = 3, + MLX5_SQP_SYNC_UMR = 4, +}; + +enum { + MLX5_MAX_PORTS = 2, +}; + +enum { + MLX5_EQ_VEC_PAGES = 0, + MLX5_EQ_VEC_CMD = 1, + MLX5_EQ_VEC_ASYNC = 2, + MLX5_EQ_VEC_COMP_BASE, +}; + +enum { + MLX5_MAX_EQ_NAME = 20 +}; + +enum { + MLX5_ATOMIC_MODE_IB_COMP = 1 << 16, + MLX5_ATOMIC_MODE_CX = 2 << 16, + MLX5_ATOMIC_MODE_8B = 3 << 16, + MLX5_ATOMIC_MODE_16B = 4 << 16, + MLX5_ATOMIC_MODE_32B = 5 << 16, + MLX5_ATOMIC_MODE_64B = 6 << 16, + MLX5_ATOMIC_MODE_128B = 7 << 16, + MLX5_ATOMIC_MODE_256B = 8 << 16, +}; + +enum { + MLX5_CMD_OP_QUERY_HCA_CAP = 0x100, + MLX5_CMD_OP_QUERY_ADAPTER = 0x101, + MLX5_CMD_OP_INIT_HCA = 0x102, + MLX5_CMD_OP_TEARDOWN_HCA = 0x103, + MLX5_CMD_OP_ENABLE_HCA = 0x104, + MLX5_CMD_OP_DISABLE_HCA = 0x105, + MLX5_CMD_OP_QUERY_PAGES = 0x107, + MLX5_CMD_OP_MANAGE_PAGES = 0x108, + MLX5_CMD_OP_SET_HCA_CAP = 0x109, + + MLX5_CMD_OP_CREATE_MKEY = 0x200, + MLX5_CMD_OP_QUERY_MKEY = 0x201, + MLX5_CMD_OP_DESTROY_MKEY = 0x202, + MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS = 0x203, + + MLX5_CMD_OP_CREATE_EQ = 0x301, + MLX5_CMD_OP_DESTROY_EQ = 0x302, + MLX5_CMD_OP_QUERY_EQ = 0x303, + + MLX5_CMD_OP_CREATE_CQ = 0x400, + MLX5_CMD_OP_DESTROY_CQ = 0x401, + MLX5_CMD_OP_QUERY_CQ = 0x402, + MLX5_CMD_OP_MODIFY_CQ = 0x403, + + MLX5_CMD_OP_CREATE_QP = 0x500, + MLX5_CMD_OP_DESTROY_QP = 0x501, + MLX5_CMD_OP_RST2INIT_QP = 0x502, + MLX5_CMD_OP_INIT2RTR_QP = 0x503, + MLX5_CMD_OP_RTR2RTS_QP = 0x504, + MLX5_CMD_OP_RTS2RTS_QP = 0x505, + MLX5_CMD_OP_SQERR2RTS_QP = 0x506, + MLX5_CMD_OP_2ERR_QP = 0x507, + MLX5_CMD_OP_RTS2SQD_QP = 0x508, + MLX5_CMD_OP_SQD2RTS_QP = 0x509, + MLX5_CMD_OP_2RST_QP = 0x50a, + MLX5_CMD_OP_QUERY_QP = 0x50b, + MLX5_CMD_OP_CONF_SQP = 0x50c, + MLX5_CMD_OP_MAD_IFC = 0x50d, + MLX5_CMD_OP_INIT2INIT_QP = 0x50e, + MLX5_CMD_OP_SUSPEND_QP = 0x50f, + MLX5_CMD_OP_UNSUSPEND_QP = 0x510, + MLX5_CMD_OP_SQD2SQD_QP = 0x511, + MLX5_CMD_OP_ALLOC_QP_COUNTER_SET = 0x512, + MLX5_CMD_OP_DEALLOC_QP_COUNTER_SET = 0x513, + MLX5_CMD_OP_QUERY_QP_COUNTER_SET = 0x514, + + MLX5_CMD_OP_CREATE_PSV = 0x600, + MLX5_CMD_OP_DESTROY_PSV = 0x601, + MLX5_CMD_OP_QUERY_PSV = 0x602, + MLX5_CMD_OP_QUERY_SIG_RULE_TABLE = 0x603, + MLX5_CMD_OP_QUERY_BLOCK_SIZE_TABLE = 0x604, + + MLX5_CMD_OP_CREATE_SRQ = 0x700, + MLX5_CMD_OP_DESTROY_SRQ = 0x701, + MLX5_CMD_OP_QUERY_SRQ = 0x702, + MLX5_CMD_OP_ARM_RQ = 0x703, + MLX5_CMD_OP_RESIZE_SRQ = 0x704, + + MLX5_CMD_OP_ALLOC_PD = 0x800, + MLX5_CMD_OP_DEALLOC_PD = 0x801, + MLX5_CMD_OP_ALLOC_UAR = 0x802, + MLX5_CMD_OP_DEALLOC_UAR = 0x803, + + MLX5_CMD_OP_ATTACH_TO_MCG = 0x806, + MLX5_CMD_OP_DETACH_FROM_MCG = 0x807, + + + MLX5_CMD_OP_ALLOC_XRCD = 0x80e, + MLX5_CMD_OP_DEALLOC_XRCD = 0x80f, + + MLX5_CMD_OP_ACCESS_REG = 0x805, + MLX5_CMD_OP_MAX = 0x810, +}; + +enum { + MLX5_REG_PCAP = 0x5001, + MLX5_REG_PMTU = 0x5003, + MLX5_REG_PTYS = 0x5004, + MLX5_REG_PAOS = 0x5006, + MLX5_REG_PMAOS = 0x5012, + MLX5_REG_PUDE = 0x5009, + MLX5_REG_PMPE = 0x5010, + MLX5_REG_PELC = 0x500e, + MLX5_REG_PMLP = 0, /* TBD */ + MLX5_REG_NODE_DESC = 0x6001, + MLX5_REG_HOST_ENDIANNESS = 0x7004, +}; + +enum dbg_rsc_type { + MLX5_DBG_RSC_QP, + MLX5_DBG_RSC_EQ, + MLX5_DBG_RSC_CQ, +}; + +struct mlx5_field_desc { + struct dentry *dent; + int i; +}; + +struct mlx5_rsc_debug { + struct mlx5_core_dev *dev; + void *object; + enum dbg_rsc_type type; + struct dentry *root; + struct mlx5_field_desc fields[0]; +}; + +enum mlx5_dev_event { + MLX5_DEV_EVENT_SYS_ERROR, + MLX5_DEV_EVENT_PORT_UP, + MLX5_DEV_EVENT_PORT_DOWN, + MLX5_DEV_EVENT_PORT_INITIALIZED, + MLX5_DEV_EVENT_LID_CHANGE, + MLX5_DEV_EVENT_PKEY_CHANGE, + MLX5_DEV_EVENT_GUID_CHANGE, + MLX5_DEV_EVENT_CLIENT_REREG, +}; + +struct mlx5_uuar_info { + struct mlx5_uar *uars; + int num_uars; + int num_low_latency_uuars; + unsigned long *bitmap; + unsigned int *count; + struct mlx5_bf *bfs; + + /* + * protect uuar allocation data structs + */ + struct mutex lock; +}; + +struct mlx5_bf { + void __iomem *reg; + void __iomem *regreg; + int buf_size; + struct mlx5_uar *uar; + unsigned long offset; + int need_lock; + /* protect blue flame buffer selection when needed + */ + spinlock_t lock; + + /* serialize 64 bit writes when done as two 32 bit accesses + */ + spinlock_t lock32; + int uuarn; +}; + +struct mlx5_cmd_first { + __be32 data[4]; +}; + +struct mlx5_cmd_msg { + struct list_head list; + struct cache_ent *cache; + u32 len; + struct mlx5_cmd_first first; + struct mlx5_cmd_mailbox *next; +}; + +struct mlx5_cmd_debug { + struct dentry *dbg_root; + struct dentry *dbg_in; + struct dentry *dbg_out; + struct dentry *dbg_outlen; + struct dentry *dbg_status; + struct dentry *dbg_run; + void *in_msg; + void *out_msg; + u8 status; + u16 inlen; + u16 outlen; +}; + +struct cache_ent { + /* protect block chain allocations + */ + spinlock_t lock; + struct list_head head; +}; + +struct cmd_msg_cache { + struct cache_ent large; + struct cache_ent med; + +}; + +struct mlx5_cmd_stats { + u64 sum; + u64 n; + struct dentry *root; + struct dentry *avg; + struct dentry *count; + /* protect command average calculations */ + spinlock_t lock; +}; + +struct mlx5_cmd { + void *cmd_buf; + dma_addr_t dma; + u16 cmdif_rev; + u8 log_sz; + u8 log_stride; + int max_reg_cmds; + int events; + u32 __iomem *vector; + + /* protect command queue allocations + */ + spinlock_t alloc_lock; + + /* protect token allocations + */ + spinlock_t token_lock; + u8 token; + unsigned long bitmask; + char wq_name[MLX5_CMD_WQ_MAX_NAME]; + struct workqueue_struct *wq; + struct semaphore sem; + struct semaphore pages_sem; + int mode; + struct mlx5_cmd_work_ent *ent_arr[MLX5_MAX_COMMANDS]; + struct pci_pool *pool; + struct mlx5_cmd_debug dbg; + struct cmd_msg_cache cache; + int checksum_disabled; + struct mlx5_cmd_stats stats[MLX5_CMD_OP_MAX]; +}; + +struct mlx5_port_caps { + int gid_table_len; + int pkey_table_len; +}; + +struct mlx5_caps { + u8 log_max_eq; + u8 log_max_cq; + u8 log_max_qp; + u8 log_max_mkey; + u8 log_max_pd; + u8 log_max_srq; + u32 max_cqes; + int max_wqes; + int max_sq_desc_sz; + int max_rq_desc_sz; + u64 flags; + u16 stat_rate_support; + int log_max_msg; + int num_ports; + int max_ra_res_qp; + int max_ra_req_qp; + int max_srq_wqes; + int bf_reg_size; + int bf_regs_per_page; + struct mlx5_port_caps port[MLX5_MAX_PORTS]; + u8 ext_port_cap[MLX5_MAX_PORTS]; + int max_vf; + u32 reserved_lkey; + u8 local_ca_ack_delay; + u8 log_max_mcg; + u32 max_qp_mcg; + int min_page_sz; +}; + +struct mlx5_cmd_mailbox { + void *buf; + dma_addr_t dma; + struct mlx5_cmd_mailbox *next; +}; + +struct mlx5_buf_list { + void *buf; + dma_addr_t map; +}; + +struct mlx5_buf { + struct mlx5_buf_list direct; + struct mlx5_buf_list *page_list; + int nbufs; + int npages; + int page_shift; + int size; +}; + +struct mlx5_eq { + struct mlx5_core_dev *dev; + __be32 __iomem *doorbell; + u32 cons_index; + struct mlx5_buf buf; + int size; + u8 irqn; + u8 eqn; + int nent; + u64 mask; + char name[MLX5_MAX_EQ_NAME]; + struct list_head list; + int index; + struct mlx5_rsc_debug *dbg; +}; + + +struct mlx5_core_mr { + u64 iova; + u64 size; + u32 key; + u32 pd; + u32 access; +}; + +struct mlx5_core_srq { + u32 srqn; + int max; + int max_gs; + int max_avail_gather; + int wqe_shift; + void (*event) (struct mlx5_core_srq *, enum mlx5_event); + + atomic_t refcount; + struct completion free; +}; + +struct mlx5_eq_table { + void __iomem *update_ci; + void __iomem *update_arm_ci; + struct list_head *comp_eq_head; + struct mlx5_eq pages_eq; + struct mlx5_eq async_eq; + struct mlx5_eq cmd_eq; + struct msix_entry *msix_arr; + int num_comp_vectors; + /* protect EQs list + */ + spinlock_t lock; +}; + +struct mlx5_uar { + u32 index; + struct list_head bf_list; + unsigned free_bf_bmap; + void __iomem *wc_map; + void __iomem *map; +}; + + +struct mlx5_core_health { + struct health_buffer __iomem *health; + __be32 __iomem *health_counter; + struct timer_list timer; + struct list_head list; + u32 prev; + int miss_counter; +}; + +struct mlx5_cq_table { + /* protect radix tree + */ + spinlock_t lock; + struct radix_tree_root tree; +}; + +struct mlx5_qp_table { + /* protect radix tree + */ + spinlock_t lock; + struct radix_tree_root tree; +}; + +struct mlx5_srq_table { + /* protect radix tree + */ + spinlock_t lock; + struct radix_tree_root tree; +}; + +struct mlx5_priv { + char name[MLX5_MAX_NAME_LEN]; + struct mlx5_eq_table eq_table; + struct mlx5_uuar_info uuari; + MLX5_DECLARE_DOORBELL_LOCK(cq_uar_lock); + + /* pages stuff */ + struct workqueue_struct *pg_wq; + struct rb_root page_root; + int fw_pages; + int reg_pages; + + struct mlx5_core_health health; + + struct mlx5_srq_table srq_table; + + /* start: qp staff */ + struct mlx5_qp_table qp_table; + struct dentry *qp_debugfs; + struct dentry *eq_debugfs; + struct dentry *cq_debugfs; + struct dentry *cmdif_debugfs; + /* end: qp staff */ + + /* start: cq staff */ + struct mlx5_cq_table cq_table; + /* end: cq staff */ + + /* start: alloc staff */ + struct mutex pgdir_mutex; + struct list_head pgdir_list; + /* end: alloc staff */ + struct dentry *dbg_root; + + /* protect mkey key part */ + spinlock_t mkey_lock; + u8 mkey_key; +}; + +struct mlx5_core_dev { + struct pci_dev *pdev; + u8 rev_id; + char board_id[MLX5_BOARD_ID_LEN]; + struct mlx5_cmd cmd; + struct mlx5_caps caps; + phys_addr_t iseg_base; + struct mlx5_init_seg __iomem *iseg; + void (*event) (struct mlx5_core_dev *dev, + enum mlx5_dev_event event, + void *data); + struct mlx5_priv priv; + struct mlx5_profile *profile; + atomic_t num_qps; +}; + +struct mlx5_db { + __be32 *db; + union { + struct mlx5_db_pgdir *pgdir; + struct mlx5_ib_user_db_page *user_page; + } u; + dma_addr_t dma; + int index; +}; + +enum { + MLX5_DB_PER_PAGE = PAGE_SIZE / L1_CACHE_BYTES, +}; + +enum { + MLX5_COMP_EQ_SIZE = 1024, +}; + +struct mlx5_db_pgdir { + struct list_head list; + DECLARE_BITMAP(bitmap, MLX5_DB_PER_PAGE); + __be32 *db_page; + dma_addr_t db_dma; +}; + +typedef void (*mlx5_cmd_cbk_t)(int status, void *context); + +struct mlx5_cmd_work_ent { + struct mlx5_cmd_msg *in; + struct mlx5_cmd_msg *out; + mlx5_cmd_cbk_t callback; + void *context; + int idx; + struct completion done; + struct mlx5_cmd *cmd; + struct work_struct work; + struct mlx5_cmd_layout *lay; + int ret; + int page_queue; + u8 status; + u8 token; + struct timespec ts1; + struct timespec ts2; +}; + +struct mlx5_pas { + u64 pa; + u8 log_sz; +}; + +static inline void *mlx5_buf_offset(struct mlx5_buf *buf, int offset) +{ + if (likely(BITS_PER_LONG == 64 || buf->nbufs == 1)) + return buf->direct.buf + offset; + else + return buf->page_list[offset >> PAGE_SHIFT].buf + + (offset & (PAGE_SIZE - 1)); +} + +extern struct workqueue_struct *mlx5_core_wq; + +#define STRUCT_FIELD(header, field) \ + .struct_offset_bytes = offsetof(struct ib_unpacked_ ## header, field), \ + .struct_size_bytes = sizeof((struct ib_unpacked_ ## header *)0)->field + +struct ib_field { + size_t struct_offset_bytes; + size_t struct_size_bytes; + int offset_bits; + int size_bits; +}; + +static inline struct mlx5_core_dev *pci2mlx5_core_dev(struct pci_dev *pdev) +{ + return pci_get_drvdata(pdev); +} + +extern struct dentry *mlx5_debugfs_root; + +static inline u16 fw_rev_maj(struct mlx5_core_dev *dev) +{ + return ioread32be(&dev->iseg->fw_rev) & 0xffff; +} + +static inline u16 fw_rev_min(struct mlx5_core_dev *dev) +{ + return ioread32be(&dev->iseg->fw_rev) >> 16; +} + +static inline u16 fw_rev_sub(struct mlx5_core_dev *dev) +{ + return ioread32be(&dev->iseg->cmdif_rev_fw_sub) & 0xffff; +} + +static inline u16 cmdif_rev(struct mlx5_core_dev *dev) +{ + return ioread32be(&dev->iseg->cmdif_rev_fw_sub) >> 16; +} + +static inline void *mlx5_vzalloc(unsigned long size) +{ + void *rtn; + + rtn = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); + if (!rtn) + rtn = vzalloc(size); + return rtn; +} + +static inline void mlx5_vfree(const void *addr) +{ + if (addr && is_vmalloc_addr(addr)) + vfree(addr); + else + kfree(addr); +} + +int mlx5_dev_init(struct mlx5_core_dev *dev, struct pci_dev *pdev); +void mlx5_dev_cleanup(struct mlx5_core_dev *dev); +int mlx5_cmd_init(struct mlx5_core_dev *dev); +void mlx5_cmd_cleanup(struct mlx5_core_dev *dev); +void mlx5_cmd_use_events(struct mlx5_core_dev *dev); +void mlx5_cmd_use_polling(struct mlx5_core_dev *dev); +int mlx5_cmd_status_to_err(struct mlx5_outbox_hdr *hdr); +int mlx5_cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out, + int out_size); +int mlx5_cmd_alloc_uar(struct mlx5_core_dev *dev, u32 *uarn); +int mlx5_cmd_free_uar(struct mlx5_core_dev *dev, u32 uarn); +int mlx5_alloc_uuars(struct mlx5_core_dev *dev, struct mlx5_uuar_info *uuari); +int mlx5_free_uuars(struct mlx5_core_dev *dev, struct mlx5_uuar_info *uuari); +void mlx5_health_cleanup(void); +void __init mlx5_health_init(void); +void mlx5_start_health_poll(struct mlx5_core_dev *dev); +void mlx5_stop_health_poll(struct mlx5_core_dev *dev); +int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, int max_direct, + struct mlx5_buf *buf); +void mlx5_buf_free(struct mlx5_core_dev *dev, struct mlx5_buf *buf); +struct mlx5_cmd_mailbox *mlx5_alloc_cmd_mailbox_chain(struct mlx5_core_dev *dev, + gfp_t flags, int npages); +void mlx5_free_cmd_mailbox_chain(struct mlx5_core_dev *dev, + struct mlx5_cmd_mailbox *head); +int mlx5_core_create_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, + struct mlx5_create_srq_mbox_in *in, int inlen); +int mlx5_core_destroy_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq); +int mlx5_core_query_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, + struct mlx5_query_srq_mbox_out *out); +int mlx5_core_arm_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, + u16 lwm, int is_srq); +int mlx5_core_create_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr, + struct mlx5_create_mkey_mbox_in *in, int inlen); +int mlx5_core_destroy_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr); +int mlx5_core_query_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr, + struct mlx5_query_mkey_mbox_out *out, int outlen); +int mlx5_core_dump_fill_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr, + u32 *mkey); +int mlx5_core_alloc_pd(struct mlx5_core_dev *dev, u32 *pdn); +int mlx5_core_dealloc_pd(struct mlx5_core_dev *dev, u32 pdn); +int mlx5_core_mad_ifc(struct mlx5_core_dev *dev, void *inb, void *outb, + u16 opmod, int port); +void mlx5_pagealloc_init(struct mlx5_core_dev *dev); +void mlx5_pagealloc_cleanup(struct mlx5_core_dev *dev); +int mlx5_pagealloc_start(struct mlx5_core_dev *dev); +void mlx5_pagealloc_stop(struct mlx5_core_dev *dev); +void mlx5_core_req_pages_handler(struct mlx5_core_dev *dev, u16 func_id, + s32 npages); +int mlx5_satisfy_startup_pages(struct mlx5_core_dev *dev, int boot); +int mlx5_reclaim_startup_pages(struct mlx5_core_dev *dev); +void mlx5_register_debugfs(void); +void mlx5_unregister_debugfs(void); +int mlx5_eq_init(struct mlx5_core_dev *dev); +void mlx5_eq_cleanup(struct mlx5_core_dev *dev); +void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas); +void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 cqn); +void mlx5_qp_event(struct mlx5_core_dev *dev, u32 qpn, int event_type); +void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type); +struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn); +void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector); +void mlx5_cq_event(struct mlx5_core_dev *dev, u32 cqn, int event_type); +int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx, + int nent, u64 mask, const char *name, struct mlx5_uar *uar); +int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq); +int mlx5_start_eqs(struct mlx5_core_dev *dev); +int mlx5_stop_eqs(struct mlx5_core_dev *dev); +int mlx5_core_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn); +int mlx5_core_detach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn); + +int mlx5_qp_debugfs_init(struct mlx5_core_dev *dev); +void mlx5_qp_debugfs_cleanup(struct mlx5_core_dev *dev); +int mlx5_core_access_reg(struct mlx5_core_dev *dev, void *data_in, + int size_in, void *data_out, int size_out, + u16 reg_num, int arg, int write); +int mlx5_set_port_caps(struct mlx5_core_dev *dev, int port_num, u32 caps); + +int mlx5_debug_eq_add(struct mlx5_core_dev *dev, struct mlx5_eq *eq); +void mlx5_debug_eq_remove(struct mlx5_core_dev *dev, struct mlx5_eq *eq); +int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq, + struct mlx5_query_eq_mbox_out *out, int outlen); +int mlx5_eq_debugfs_init(struct mlx5_core_dev *dev); +void mlx5_eq_debugfs_cleanup(struct mlx5_core_dev *dev); +int mlx5_cq_debugfs_init(struct mlx5_core_dev *dev); +void mlx5_cq_debugfs_cleanup(struct mlx5_core_dev *dev); +int mlx5_db_alloc(struct mlx5_core_dev *dev, struct mlx5_db *db); +void mlx5_db_free(struct mlx5_core_dev *dev, struct mlx5_db *db); + +const char *mlx5_command_str(int command); +int mlx5_cmdif_debugfs_init(struct mlx5_core_dev *dev); +void mlx5_cmdif_debugfs_cleanup(struct mlx5_core_dev *dev); + +static inline u32 mlx5_mkey_to_idx(u32 mkey) +{ + return mkey >> 8; +} + +static inline u32 mlx5_idx_to_mkey(u32 mkey_idx) +{ + return mkey_idx << 8; +} + +enum { + MLX5_PROF_MASK_QP_SIZE = (u64)1 << 0, + MLX5_PROF_MASK_CMDIF_CSUM = (u64)1 << 1, + MLX5_PROF_MASK_MR_CACHE = (u64)1 << 2, +}; + +enum { + MAX_MR_CACHE_ENTRIES = 16, +}; + +struct mlx5_profile { + u64 mask; + u32 log_max_qp; + int cmdif_csum; + struct { + int size; + int limit; + } mr_cache[MAX_MR_CACHE_ENTRIES]; +}; + +#endif /* MLX5_DRIVER_H */ diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h new file mode 100644 index 000000000000..d9e3eacb3a7f --- /dev/null +++ b/include/linux/mlx5/qp.h @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2013, Mellanox Technologies inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MLX5_QP_H +#define MLX5_QP_H + +#include <linux/mlx5/device.h> +#include <linux/mlx5/driver.h> + +#define MLX5_INVALID_LKEY 0x100 + +enum mlx5_qp_optpar { + MLX5_QP_OPTPAR_ALT_ADDR_PATH = 1 << 0, + MLX5_QP_OPTPAR_RRE = 1 << 1, + MLX5_QP_OPTPAR_RAE = 1 << 2, + MLX5_QP_OPTPAR_RWE = 1 << 3, + MLX5_QP_OPTPAR_PKEY_INDEX = 1 << 4, + MLX5_QP_OPTPAR_Q_KEY = 1 << 5, + MLX5_QP_OPTPAR_RNR_TIMEOUT = 1 << 6, + MLX5_QP_OPTPAR_PRIMARY_ADDR_PATH = 1 << 7, + MLX5_QP_OPTPAR_SRA_MAX = 1 << 8, + MLX5_QP_OPTPAR_RRA_MAX = 1 << 9, + MLX5_QP_OPTPAR_PM_STATE = 1 << 10, + MLX5_QP_OPTPAR_RETRY_COUNT = 1 << 12, + MLX5_QP_OPTPAR_RNR_RETRY = 1 << 13, + MLX5_QP_OPTPAR_ACK_TIMEOUT = 1 << 14, + MLX5_QP_OPTPAR_PRI_PORT = 1 << 16, + MLX5_QP_OPTPAR_SRQN = 1 << 18, + MLX5_QP_OPTPAR_CQN_RCV = 1 << 19, + MLX5_QP_OPTPAR_DC_HS = 1 << 20, + MLX5_QP_OPTPAR_DC_KEY = 1 << 21, +}; + +enum mlx5_qp_state { + MLX5_QP_STATE_RST = 0, + MLX5_QP_STATE_INIT = 1, + MLX5_QP_STATE_RTR = 2, + MLX5_QP_STATE_RTS = 3, + MLX5_QP_STATE_SQER = 4, + MLX5_QP_STATE_SQD = 5, + MLX5_QP_STATE_ERR = 6, + MLX5_QP_STATE_SQ_DRAINING = 7, + MLX5_QP_STATE_SUSPENDED = 9, + MLX5_QP_NUM_STATE +}; + +enum { + MLX5_QP_ST_RC = 0x0, + MLX5_QP_ST_UC = 0x1, + MLX5_QP_ST_UD = 0x2, + MLX5_QP_ST_XRC = 0x3, + MLX5_QP_ST_MLX = 0x4, + MLX5_QP_ST_DCI = 0x5, + MLX5_QP_ST_DCT = 0x6, + MLX5_QP_ST_QP0 = 0x7, + MLX5_QP_ST_QP1 = 0x8, + MLX5_QP_ST_RAW_ETHERTYPE = 0x9, + MLX5_QP_ST_RAW_IPV6 = 0xa, + MLX5_QP_ST_SNIFFER = 0xb, + MLX5_QP_ST_SYNC_UMR = 0xe, + MLX5_QP_ST_PTP_1588 = 0xd, + MLX5_QP_ST_REG_UMR = 0xc, + MLX5_QP_ST_MAX +}; + +enum { + MLX5_QP_PM_MIGRATED = 0x3, + MLX5_QP_PM_ARMED = 0x0, + MLX5_QP_PM_REARM = 0x1 +}; + +enum { + MLX5_NON_ZERO_RQ = 0 << 24, + MLX5_SRQ_RQ = 1 << 24, + MLX5_CRQ_RQ = 2 << 24, + MLX5_ZERO_LEN_RQ = 3 << 24 +}; + +enum { + /* params1 */ + MLX5_QP_BIT_SRE = 1 << 15, + MLX5_QP_BIT_SWE = 1 << 14, + MLX5_QP_BIT_SAE = 1 << 13, + /* params2 */ + MLX5_QP_BIT_RRE = 1 << 15, + MLX5_QP_BIT_RWE = 1 << 14, + MLX5_QP_BIT_RAE = 1 << 13, + MLX5_QP_BIT_RIC = 1 << 4, +}; + +enum { + MLX5_WQE_CTRL_CQ_UPDATE = 2 << 2, + MLX5_WQE_CTRL_SOLICITED = 1 << 1, +}; + +enum { + MLX5_SEND_WQE_BB = 64, +}; + +enum { + MLX5_WQE_FMR_PERM_LOCAL_READ = 1 << 27, + MLX5_WQE_FMR_PERM_LOCAL_WRITE = 1 << 28, + MLX5_WQE_FMR_PERM_REMOTE_READ = 1 << 29, + MLX5_WQE_FMR_PERM_REMOTE_WRITE = 1 << 30, + MLX5_WQE_FMR_PERM_ATOMIC = 1 << 31 +}; + +enum { + MLX5_FENCE_MODE_NONE = 0 << 5, + MLX5_FENCE_MODE_INITIATOR_SMALL = 1 << 5, + MLX5_FENCE_MODE_STRONG_ORDERING = 3 << 5, + MLX5_FENCE_MODE_SMALL_AND_FENCE = 4 << 5, +}; + +enum { + MLX5_QP_LAT_SENSITIVE = 1 << 28, + MLX5_QP_ENABLE_SIG = 1 << 31, +}; + +enum { + MLX5_RCV_DBR = 0, + MLX5_SND_DBR = 1, +}; + +struct mlx5_wqe_fmr_seg { + __be32 flags; + __be32 mem_key; + __be64 buf_list; + __be64 start_addr; + __be64 reg_len; + __be32 offset; + __be32 page_size; + u32 reserved[2]; +}; + +struct mlx5_wqe_ctrl_seg { + __be32 opmod_idx_opcode; + __be32 qpn_ds; + u8 signature; + u8 rsvd[2]; + u8 fm_ce_se; + __be32 imm; +}; + +struct mlx5_wqe_xrc_seg { + __be32 xrc_srqn; + u8 rsvd[12]; +}; + +struct mlx5_wqe_masked_atomic_seg { + __be64 swap_add; + __be64 compare; + __be64 swap_add_mask; + __be64 compare_mask; +}; + +struct mlx5_av { + union { + struct { + __be32 qkey; + __be32 reserved; + } qkey; + __be64 dc_key; + } key; + __be32 dqp_dct; + u8 stat_rate_sl; + u8 fl_mlid; + __be16 rlid; + u8 reserved0[10]; + u8 tclass; + u8 hop_limit; + __be32 grh_gid_fl; + u8 rgid[16]; +}; + +struct mlx5_wqe_datagram_seg { + struct mlx5_av av; +}; + +struct mlx5_wqe_raddr_seg { + __be64 raddr; + __be32 rkey; + u32 reserved; +}; + +struct mlx5_wqe_atomic_seg { + __be64 swap_add; + __be64 compare; +}; + +struct mlx5_wqe_data_seg { + __be32 byte_count; + __be32 lkey; + __be64 addr; +}; + +struct mlx5_wqe_umr_ctrl_seg { + u8 flags; + u8 rsvd0[3]; + __be16 klm_octowords; + __be16 bsf_octowords; + __be64 mkey_mask; + u8 rsvd1[32]; +}; + +struct mlx5_seg_set_psv { + __be32 psv_num; + __be16 syndrome; + __be16 status; + __be32 transient_sig; + __be32 ref_tag; +}; + +struct mlx5_seg_get_psv { + u8 rsvd[19]; + u8 num_psv; + __be32 l_key; + __be64 va; + __be32 psv_index[4]; +}; + +struct mlx5_seg_check_psv { + u8 rsvd0[2]; + __be16 err_coalescing_op; + u8 rsvd1[2]; + __be16 xport_err_op; + u8 rsvd2[2]; + __be16 xport_err_mask; + u8 rsvd3[7]; + u8 num_psv; + __be32 l_key; + __be64 va; + __be32 psv_index[4]; +}; + +struct mlx5_rwqe_sig { + u8 rsvd0[4]; + u8 signature; + u8 rsvd1[11]; +}; + +struct mlx5_wqe_signature_seg { + u8 rsvd0[4]; + u8 signature; + u8 rsvd1[11]; +}; + +struct mlx5_wqe_inline_seg { + __be32 byte_count; +}; + +struct mlx5_core_qp { + void (*event) (struct mlx5_core_qp *, int); + int qpn; + atomic_t refcount; + struct completion free; + struct mlx5_rsc_debug *dbg; + int pid; +}; + +struct mlx5_qp_path { + u8 fl; + u8 rsvd3; + u8 free_ar; + u8 pkey_index; + u8 rsvd0; + u8 grh_mlid; + __be16 rlid; + u8 ackto_lt; + u8 mgid_index; + u8 static_rate; + u8 hop_limit; + __be32 tclass_flowlabel; + u8 rgid[16]; + u8 rsvd1[4]; + u8 sl; + u8 port; + u8 rsvd2[6]; +}; + +struct mlx5_qp_context { + __be32 flags; + __be32 flags_pd; + u8 mtu_msgmax; + u8 rq_size_stride; + __be16 sq_crq_size; + __be32 qp_counter_set_usr_page; + __be32 wire_qpn; + __be32 log_pg_sz_remote_qpn; + struct mlx5_qp_path pri_path; + struct mlx5_qp_path alt_path; + __be32 params1; + u8 reserved2[4]; + __be32 next_send_psn; + __be32 cqn_send; + u8 reserved3[8]; + __be32 last_acked_psn; + __be32 ssn; + __be32 params2; + __be32 rnr_nextrecvpsn; + __be32 xrcd; + __be32 cqn_recv; + __be64 db_rec_addr; + __be32 qkey; + __be32 rq_type_srqn; + __be32 rmsn; + __be16 hw_sq_wqe_counter; + __be16 sw_sq_wqe_counter; + __be16 hw_rcyclic_byte_counter; + __be16 hw_rq_counter; + __be16 sw_rcyclic_byte_counter; + __be16 sw_rq_counter; + u8 rsvd0[5]; + u8 cgs; + u8 cs_req; + u8 cs_res; + __be64 dc_access_key; + u8 rsvd1[24]; +}; + +struct mlx5_create_qp_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 input_qpn; + u8 rsvd0[4]; + __be32 opt_param_mask; + u8 rsvd1[4]; + struct mlx5_qp_context ctx; + u8 rsvd3[16]; + __be64 pas[0]; +}; + +struct mlx5_create_qp_mbox_out { + struct mlx5_outbox_hdr hdr; + __be32 qpn; + u8 rsvd0[4]; +}; + +struct mlx5_destroy_qp_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 qpn; + u8 rsvd0[4]; +}; + +struct mlx5_destroy_qp_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd0[8]; +}; + +struct mlx5_modify_qp_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 qpn; + u8 rsvd1[4]; + __be32 optparam; + u8 rsvd0[4]; + struct mlx5_qp_context ctx; +}; + +struct mlx5_modify_qp_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd0[8]; +}; + +struct mlx5_query_qp_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 qpn; + u8 rsvd[4]; +}; + +struct mlx5_query_qp_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd1[8]; + __be32 optparam; + u8 rsvd0[4]; + struct mlx5_qp_context ctx; + u8 rsvd2[16]; + __be64 pas[0]; +}; + +struct mlx5_conf_sqp_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 qpn; + u8 rsvd[3]; + u8 type; +}; + +struct mlx5_conf_sqp_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_alloc_xrcd_mbox_in { + struct mlx5_inbox_hdr hdr; + u8 rsvd[8]; +}; + +struct mlx5_alloc_xrcd_mbox_out { + struct mlx5_outbox_hdr hdr; + __be32 xrcdn; + u8 rsvd[4]; +}; + +struct mlx5_dealloc_xrcd_mbox_in { + struct mlx5_inbox_hdr hdr; + __be32 xrcdn; + u8 rsvd[4]; +}; + +struct mlx5_dealloc_xrcd_mbox_out { + struct mlx5_outbox_hdr hdr; + u8 rsvd[8]; +}; + +static inline struct mlx5_core_qp *__mlx5_qp_lookup(struct mlx5_core_dev *dev, u32 qpn) +{ + return radix_tree_lookup(&dev->priv.qp_table.tree, qpn); +} + +int mlx5_core_create_qp(struct mlx5_core_dev *dev, + struct mlx5_core_qp *qp, + struct mlx5_create_qp_mbox_in *in, + int inlen); +int mlx5_core_qp_modify(struct mlx5_core_dev *dev, enum mlx5_qp_state cur_state, + enum mlx5_qp_state new_state, + struct mlx5_modify_qp_mbox_in *in, int sqd_event, + struct mlx5_core_qp *qp); +int mlx5_core_destroy_qp(struct mlx5_core_dev *dev, + struct mlx5_core_qp *qp); +int mlx5_core_qp_query(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp, + struct mlx5_query_qp_mbox_out *out, int outlen); + +int mlx5_core_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn); +int mlx5_core_xrcd_dealloc(struct mlx5_core_dev *dev, u32 xrcdn); +void mlx5_init_qp_table(struct mlx5_core_dev *dev); +void mlx5_cleanup_qp_table(struct mlx5_core_dev *dev); +int mlx5_debug_qp_add(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp); +void mlx5_debug_qp_remove(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp); + +#endif /* MLX5_QP_H */ diff --git a/include/linux/mlx5/srq.h b/include/linux/mlx5/srq.h new file mode 100644 index 000000000000..e1a363a33663 --- /dev/null +++ b/include/linux/mlx5/srq.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, Mellanox Technologies inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef MLX5_SRQ_H +#define MLX5_SRQ_H + +#include <linux/mlx5/driver.h> + +void mlx5_init_srq_table(struct mlx5_core_dev *dev); +void mlx5_cleanup_srq_table(struct mlx5_core_dev *dev); + +#endif /* MLX5_SRQ_H */ diff --git a/include/linux/mm.h b/include/linux/mm.h index 7acc9dc73c9f..8b6e55ee8855 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -25,11 +25,17 @@ struct file_ra_state; struct user_struct; struct writeback_control; -#ifndef CONFIG_DISCONTIGMEM /* Don't use mapnrs, do it properly */ +#ifndef CONFIG_NEED_MULTIPLE_NODES /* Don't use mapnrs, do it properly */ extern unsigned long max_mapnr; + +static inline void set_max_mapnr(unsigned long limit) +{ + max_mapnr = limit; +} +#else +static inline void set_max_mapnr(unsigned long limit) { } #endif -extern unsigned long num_physpages; extern unsigned long totalram_pages; extern void * high_memory; extern int page_cluster; @@ -44,11 +50,17 @@ extern int sysctl_legacy_va_layout; #include <asm/pgtable.h> #include <asm/processor.h> +extern unsigned long sysctl_user_reserve_kbytes; +extern unsigned long sysctl_admin_reserve_kbytes; + #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n)) /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE) +/* test whether an address (unsigned long or pointer) is aligned to PAGE_SIZE */ +#define PAGE_ALIGNED(addr) IS_ALIGNED((unsigned long)addr, PAGE_SIZE) + /* * Linux kernel virtual memory manager primitives. * The idea being to have a "virtual" mm in the same way @@ -87,7 +99,6 @@ extern unsigned int kobjsize(const void *objp); #define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */ #define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */ -#define VM_POPULATE 0x00001000 #define VM_LOCKED 0x00002000 #define VM_IO 0x00004000 /* Memory mapped I/O or similar */ @@ -104,6 +115,12 @@ extern unsigned int kobjsize(const void *objp); #define VM_ARCH_1 0x01000000 /* Architecture-specific flag */ #define VM_DONTDUMP 0x04000000 /* Do not include in the core dump */ +#ifdef CONFIG_MEM_SOFT_DIRTY +# define VM_SOFTDIRTY 0x08000000 /* Not soft dirty clean area */ +#else +# define VM_SOFTDIRTY 0 +#endif + #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */ #define VM_HUGEPAGE 0x20000000 /* MADV_HUGEPAGE marked this vma */ #define VM_NOHUGEPAGE 0x40000000 /* MADV_NOHUGEPAGE marked this vma */ @@ -140,12 +157,6 @@ extern unsigned int kobjsize(const void *objp); #define VM_STACK_FLAGS (VM_GROWSDOWN | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT) #endif -#define VM_READHINTMASK (VM_SEQ_READ | VM_RAND_READ) -#define VM_ClearReadHint(v) (v)->vm_flags &= ~VM_READHINTMASK -#define VM_NormalReadHint(v) (!((v)->vm_flags & VM_READHINTMASK)) -#define VM_SequentialReadHint(v) ((v)->vm_flags & VM_SEQ_READ) -#define VM_RandomReadHint(v) ((v)->vm_flags & VM_RAND_READ) - /* * Special vmas that are non-mergable, non-mlock()able. * Note: mm/huge_memory.c VM_NO_THP depends on this definition. @@ -165,6 +176,7 @@ extern pgprot_t protection_map[16]; #define FAULT_FLAG_RETRY_NOWAIT 0x10 /* Don't drop mmap_sem and wait when retrying */ #define FAULT_FLAG_KILLABLE 0x20 /* The fault task is in SIGKILL killable region */ #define FAULT_FLAG_TRIED 0x40 /* second try */ +#define FAULT_FLAG_USER 0x80 /* The fault originated in userspace */ /* * vm_fault is filled by the the pagefault handler and passed to the vma's @@ -484,20 +496,6 @@ static inline int compound_order(struct page *page) return (unsigned long)page[1].lru.prev; } -static inline int compound_trans_order(struct page *page) -{ - int order; - unsigned long flags; - - if (!PageHead(page)) - return 0; - - flags = compound_lock_irqsave(page); - order = compound_order(page); - compound_unlock_irqrestore(page, flags); - return order; -} - static inline void set_compound_order(struct page *page, unsigned long order) { page[1].lru.prev = (void *)order; @@ -632,12 +630,12 @@ static inline enum zone_type page_zonenum(const struct page *page) #endif /* - * The identification function is only used by the buddy allocator for - * determining if two pages could be buddies. We are not really - * identifying a zone since we could be using a the section number - * id if we have not node id available in page flags. - * We guarantee only that it will return the same value for two - * combinable pages in a zone. + * The identification function is mainly used by the buddy allocator for + * determining if two pages could be buddies. We are not really identifying + * the zone since we could be using the section number id if we do not have + * node id available in page flags. + * We only guarantee that it will return the same value for two combinable + * pages in a zone. */ static inline int page_zone_id(struct page *page) { @@ -879,11 +877,12 @@ static inline int page_mapped(struct page *page) #define VM_FAULT_NOPAGE 0x0100 /* ->fault installed the pte, not return page */ #define VM_FAULT_LOCKED 0x0200 /* ->fault locked the returned page */ #define VM_FAULT_RETRY 0x0400 /* ->fault blocked, must retry */ +#define VM_FAULT_FALLBACK 0x0800 /* huge page fault failed, fall back to small */ #define VM_FAULT_HWPOISON_LARGE_MASK 0xf000 /* encodes hpage index for large hwpoison */ #define VM_FAULT_ERROR (VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_HWPOISON | \ - VM_FAULT_HWPOISON_LARGE) + VM_FAULT_FALLBACK | VM_FAULT_HWPOISON_LARGE) /* Encode hstate index for a hwpoisoned large page */ #define VM_FAULT_SET_HINDEX(x) ((x) << 12) @@ -900,7 +899,8 @@ extern void pagefault_out_of_memory(void); * Flags passed to show_mem() and show_free_areas() to suppress output in * various contexts. */ -#define SHOW_MEM_FILTER_NODES (0x0001u) /* filter disallowed nodes */ +#define SHOW_MEM_FILTER_NODES (0x0001u) /* disallowed nodes */ +#define SHOW_MEM_FILTER_PAGE_COUNT (0x0002u) /* page type count */ extern void show_free_areas(unsigned int flags); extern bool skip_free_areas_node(unsigned int flags, int nid); @@ -948,13 +948,19 @@ void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *start_vma, * (see walk_page_range for more details) */ struct mm_walk { - int (*pgd_entry)(pgd_t *, unsigned long, unsigned long, struct mm_walk *); - int (*pud_entry)(pud_t *, unsigned long, unsigned long, struct mm_walk *); - int (*pmd_entry)(pmd_t *, unsigned long, unsigned long, struct mm_walk *); - int (*pte_entry)(pte_t *, unsigned long, unsigned long, struct mm_walk *); - int (*pte_hole)(unsigned long, unsigned long, struct mm_walk *); - int (*hugetlb_entry)(pte_t *, unsigned long, - unsigned long, unsigned long, struct mm_walk *); + int (*pgd_entry)(pgd_t *pgd, unsigned long addr, + unsigned long next, struct mm_walk *walk); + int (*pud_entry)(pud_t *pud, unsigned long addr, + unsigned long next, struct mm_walk *walk); + int (*pmd_entry)(pmd_t *pmd, unsigned long addr, + unsigned long next, struct mm_walk *walk); + int (*pte_entry)(pte_t *pte, unsigned long addr, + unsigned long next, struct mm_walk *walk); + int (*pte_hole)(unsigned long addr, unsigned long next, + struct mm_walk *walk); + int (*hugetlb_entry)(pte_t *pte, unsigned long hmask, + unsigned long addr, unsigned long next, + struct mm_walk *walk); struct mm_struct *mm; void *private; }; @@ -980,7 +986,7 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, unmap_mapping_range(mapping, holebegin, holelen, 0); } -extern void truncate_pagecache(struct inode *inode, loff_t old, loff_t new); +extern void truncate_pagecache(struct inode *inode, loff_t new); extern void truncate_setsize(struct inode *inode, loff_t newsize); void truncate_pagecache_range(struct inode *inode, loff_t offset, loff_t end); int truncate_inode_page(struct address_space *mapping, struct page *page); @@ -1032,7 +1038,8 @@ int get_kernel_page(unsigned long start, int write, struct page **pages); struct page *get_dump_page(unsigned long addr); extern int try_to_release_page(struct page * page, gfp_t gfp_mask); -extern void do_invalidatepage(struct page *page, unsigned long offset); +extern void do_invalidatepage(struct page *page, unsigned int offset, + unsigned int length); int __set_page_dirty_nobuffers(struct page *page); int __set_page_dirty_no_writeback(struct page *page); @@ -1079,9 +1086,6 @@ extern unsigned long move_page_tables(struct vm_area_struct *vma, unsigned long old_addr, struct vm_area_struct *new_vma, unsigned long new_addr, unsigned long len, bool need_rmap_locks); -extern unsigned long do_mremap(unsigned long addr, - unsigned long old_len, unsigned long new_len, - unsigned long flags, unsigned long new_addr); extern unsigned long change_protection(struct vm_area_struct *vma, unsigned long start, unsigned long end, pgprot_t newprot, int dirty_accountable, int prot_numa); @@ -1295,6 +1299,71 @@ extern void free_area_init_node(int nid, unsigned long * zones_size, unsigned long zone_start_pfn, unsigned long *zholes_size); extern void free_initmem(void); +/* + * Free reserved pages within range [PAGE_ALIGN(start), end & PAGE_MASK) + * into the buddy system. The freed pages will be poisoned with pattern + * "poison" if it's within range [0, UCHAR_MAX]. + * Return pages freed into the buddy system. + */ +extern unsigned long free_reserved_area(void *start, void *end, + int poison, char *s); + +#ifdef CONFIG_HIGHMEM +/* + * Free a highmem page into the buddy system, adjusting totalhigh_pages + * and totalram_pages. + */ +extern void free_highmem_page(struct page *page); +#endif + +extern void adjust_managed_page_count(struct page *page, long count); +extern void mem_init_print_info(const char *str); + +/* Free the reserved page into the buddy system, so it gets managed. */ +static inline void __free_reserved_page(struct page *page) +{ + ClearPageReserved(page); + init_page_count(page); + __free_page(page); +} + +static inline void free_reserved_page(struct page *page) +{ + __free_reserved_page(page); + adjust_managed_page_count(page, 1); +} + +static inline void mark_page_reserved(struct page *page) +{ + SetPageReserved(page); + adjust_managed_page_count(page, -1); +} + +/* + * Default method to free all the __init memory into the buddy system. + * The freed pages will be poisoned with pattern "poison" if it's within + * range [0, UCHAR_MAX]. + * Return pages freed into the buddy system. + */ +static inline unsigned long free_initmem_default(int poison) +{ + extern char __init_begin[], __init_end[]; + + return free_reserved_area(&__init_begin, &__init_end, + poison, "unused kernel"); +} + +static inline unsigned long get_num_physpages(void) +{ + int nid; + unsigned long phys_pages = 0; + + for_each_online_node(nid) + phys_pages += node_present_pages(nid); + + return phys_pages; +} + #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP /* * With CONFIG_HAVE_MEMBLOCK_NODE_MAP set, an architecture may initialise its @@ -1612,6 +1681,8 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn); int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn); +int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len); + struct page *follow_page_mask(struct vm_area_struct *vma, unsigned long address, unsigned int foll_flags, @@ -1674,8 +1745,12 @@ int in_gate_area_no_mm(unsigned long addr); #define in_gate_area(mm, addr) ({(void)mm; in_gate_area_no_mm(addr);}) #endif /* __HAVE_ARCH_GATE_AREA */ +#ifdef CONFIG_SYSCTL +extern int sysctl_drop_caches; int drop_caches_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); +#endif + unsigned long shrink_slab(struct shrink_control *shrink, unsigned long nr_pages_scanned, unsigned long lru_pages); @@ -1703,12 +1778,12 @@ pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node); void *vmemmap_alloc_block(unsigned long size, int node); void *vmemmap_alloc_block_buf(unsigned long size, int node); void vmemmap_verify(pte_t *, int, unsigned long, unsigned long); -int vmemmap_populate_basepages(struct page *start_page, - unsigned long pages, int node); -int vmemmap_populate(struct page *start_page, unsigned long pages, int node); +int vmemmap_populate_basepages(unsigned long start, unsigned long end, + int node); +int vmemmap_populate(unsigned long start, unsigned long end, int node); void vmemmap_populate_print_last(void); #ifdef CONFIG_MEMORY_HOTPLUG -void vmemmap_free(struct page *memmap, unsigned long nr_pages); +void vmemmap_free(unsigned long start, unsigned long end); #endif void register_page_bootmem_memmap(unsigned long section_nr, struct page *map, unsigned long size); @@ -1717,6 +1792,7 @@ enum mf_flags { MF_COUNT_INCREASED = 1 << 0, MF_ACTION_REQUIRED = 1 << 1, MF_MUST_KILL = 1 << 2, + MF_SOFT_OFFLINE = 1 << 3, }; extern int memory_failure(unsigned long pfn, int trapno, int flags); extern void memory_failure_queue(unsigned long pfn, int trapno, int flags); @@ -1755,5 +1831,11 @@ static inline unsigned int debug_guardpage_minorder(void) { return 0; } static inline bool page_is_guard(struct page *page) { return false; } #endif /* CONFIG_DEBUG_PAGEALLOC */ +#if MAX_NUMNODES > 1 +void __init setup_nr_node_ids(void); +#else +static inline void setup_nr_node_ids(void) {} +#endif + #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index 1397ccf81e91..cf55945c83fb 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -2,6 +2,7 @@ #define LINUX_MM_INLINE_H #include <linux/huge_mm.h> +#include <linux/swap.h> /** * page_is_file_cache - should the page be on a file LRU or anon LRU? diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index ace9a5f01c64..d9851eeb6e1d 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -322,6 +322,7 @@ struct mm_rss_stat { atomic_long_t count[NR_MM_COUNTERS]; }; +struct kioctx_table; struct mm_struct { struct vm_area_struct * mmap; /* list of VMAs */ struct rb_root mm_rb; @@ -330,12 +331,10 @@ struct mm_struct { unsigned long (*get_unmapped_area) (struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); - void (*unmap_area) (struct mm_struct *mm, unsigned long addr); #endif unsigned long mmap_base; /* base of mmap area */ + unsigned long mmap_legacy_base; /* base of mmap area in bottom-up allocations */ unsigned long task_size; /* size of task vm space */ - unsigned long cached_hole_size; /* if non-zero, the largest hole below free_area_cache */ - unsigned long free_area_cache; /* first hole of size cached_hole_size or larger */ unsigned long highest_vm_end; /* highest vma end address */ pgd_t * pgd; atomic_t mm_users; /* How many users with user space? */ @@ -385,8 +384,8 @@ struct mm_struct { struct core_state *core_state; /* coredumping support */ #ifdef CONFIG_AIO - spinlock_t ioctx_lock; - struct hlist_head ioctx_list; + spinlock_t ioctx_lock; + struct kioctx_table __rcu *ioctx_table; #endif #ifdef CONFIG_MM_OWNER /* diff --git a/include/linux/mman.h b/include/linux/mman.h index 61c7a87e5d2b..92dc257251e4 100644 --- a/include/linux/mman.h +++ b/include/linux/mman.h @@ -11,11 +11,17 @@ extern int sysctl_overcommit_memory; extern int sysctl_overcommit_ratio; extern struct percpu_counter vm_committed_as; +#ifdef CONFIG_SMP +extern s32 vm_committed_as_batch; +#else +#define vm_committed_as_batch 0 +#endif + unsigned long vm_memory_committed(void); static inline void vm_acct_memory(long pages) { - percpu_counter_add(&vm_committed_as, pages); + __percpu_counter_add(&vm_committed_as, pages, vm_committed_as_batch); } static inline void vm_unacct_memory(long pages) @@ -79,8 +85,6 @@ calc_vm_flag_bits(unsigned long flags) { return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) | _calc_vm_trans(flags, MAP_DENYWRITE, VM_DENYWRITE ) | - ((flags & MAP_LOCKED) ? (VM_LOCKED | VM_POPULATE) : 0) | - (((flags & (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE) ? - VM_POPULATE : 0); + _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED ); } #endif /* _LINUX_MMAN_H */ diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 61b2c30c903b..f42cdbd8ac21 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -17,6 +17,7 @@ struct mmc_cid { unsigned int manfid; char prod_name[8]; + unsigned char prv; unsigned int serial; unsigned short oemid; unsigned short year; @@ -93,7 +94,11 @@ struct mmc_ext_csd { u8 raw_ext_csd_structure; /* 194 */ u8 raw_card_type; /* 196 */ u8 out_of_int_time; /* 198 */ - u8 raw_s_a_timeout; /* 217 */ + u8 raw_pwr_cl_52_195; /* 200 */ + u8 raw_pwr_cl_26_195; /* 201 */ + u8 raw_pwr_cl_52_360; /* 202 */ + u8 raw_pwr_cl_26_360; /* 203 */ + u8 raw_s_a_timeout; /* 217 */ u8 raw_hc_erase_gap_size; /* 221 */ u8 raw_erase_timeout_mult; /* 223 */ u8 raw_hc_erase_grp_size; /* 224 */ @@ -101,6 +106,10 @@ struct mmc_ext_csd { u8 raw_sec_erase_mult; /* 230 */ u8 raw_sec_feature_support;/* 231 */ u8 raw_trim_mult; /* 232 */ + u8 raw_pwr_cl_200_195; /* 236 */ + u8 raw_pwr_cl_200_360; /* 237 */ + u8 raw_pwr_cl_ddr_52_195; /* 238 */ + u8 raw_pwr_cl_ddr_52_360; /* 239 */ u8 raw_bkops_status; /* 246 */ u8 raw_sectors[4]; /* 212 - 4 bytes */ @@ -411,7 +420,6 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) #define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR) #define mmc_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED) -#define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED) #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) @@ -423,7 +431,6 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) #define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR) #define mmc_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED) -#define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED) #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) #define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS) @@ -511,6 +518,7 @@ struct mmc_driver { void (*remove)(struct mmc_card *); int (*suspend)(struct mmc_card *); int (*resume)(struct mmc_card *); + void (*shutdown)(struct mmc_card *); }; extern int mmc_register_driver(struct mmc_driver *); diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 39613b9a6fc5..a00fc49c8434 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -96,6 +96,8 @@ struct mmc_command { */ unsigned int cmd_timeout_ms; /* in milliseconds */ + /* Set this flag only for blocking sanitize request */ + bool sanitize_busy; struct mmc_data *data; /* data segment associated with cmd */ struct mmc_request *mrq; /* associated request */ @@ -186,7 +188,9 @@ extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort); extern void mmc_release_host(struct mmc_host *host); -extern int mmc_try_claim_host(struct mmc_host *host); + +extern void mmc_get_card(struct mmc_card *card); +extern void mmc_put_card(struct mmc_card *card); extern int mmc_flush_cache(struct mmc_card *); @@ -203,6 +207,8 @@ static inline void mmc_claim_host(struct mmc_host *host) __mmc_claim_host(host, NULL); } +struct device_node; extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); +extern int mmc_of_parse_voltage(struct device_node *np, u32 *mask); #endif /* LINUX_MMC_CORE_H */ diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index 198f0fa44e9f..6ce7d2cd3c7a 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h @@ -15,6 +15,7 @@ #define LINUX_MMC_DW_MMC_H #include <linux/scatterlist.h> +#include <linux/mmc/core.h> #define MAX_MCI_SLOTS 2 @@ -129,6 +130,9 @@ struct dw_mci { struct mmc_request *mrq; struct mmc_command *cmd; struct mmc_data *data; + struct mmc_command stop_abort; + unsigned int prev_blksz; + unsigned char timing; struct workqueue_struct *card_workqueue; /* DMA interface members*/ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index d6f20cc6415e..3b0c33ae13e1 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -239,7 +239,7 @@ struct mmc_host { #define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */ #define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */ #define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */ - +#define MMC_CAP_AGGRESSIVE_PM (1 << 7) /* Suspend (e)MMC/SD at idle */ #define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */ #define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */ #define MMC_CAP_ERASE (1 << 10) /* Allow erase/trim commands */ @@ -264,7 +264,7 @@ struct mmc_host { #define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */ #define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */ -#define MMC_CAP2_POWEROFF_NOTIFY (1 << 2) /* Notify poweroff supported */ +#define MMC_CAP2_FULL_PWR_CYCLE (1 << 2) /* Can do full power cycle */ #define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */ #define MMC_CAP2_NO_SLEEP_CMD (1 << 4) /* Don't allow sleep command */ #define MMC_CAP2_HS200_1_8V_SDR (1 << 5) /* can support */ @@ -272,7 +272,6 @@ struct mmc_host { #define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \ MMC_CAP2_HS200_1_2V_SDR) #define MMC_CAP2_BROKEN_VOLTAGE (1 << 7) /* Use the broken voltage */ -#define MMC_CAP2_DETECT_ON_ERR (1 << 8) /* On I/O err check card removal */ #define MMC_CAP2_HC_ERASE_SZ (1 << 9) /* High-capacity erase size */ #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */ #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */ @@ -280,6 +279,8 @@ struct mmc_host { #define MMC_CAP2_PACKED_WR (1 << 13) /* Allow packed write */ #define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \ MMC_CAP2_PACKED_WR) +#define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */ +#define MMC_CAP2_SANITIZE (1 << 15) /* Support Sanitize */ mmc_pm_flag_t pm_caps; /* supported pm features */ @@ -341,9 +342,7 @@ struct mmc_host { mmc_pm_flag_t pm_flags; /* requested pm features */ -#ifdef CONFIG_LEDS_TRIGGERS struct led_trigger *led; /* activity led */ -#endif #ifdef CONFIG_REGULATOR bool regulator_enabled; /* regulator state */ @@ -361,6 +360,8 @@ struct mmc_host { unsigned int actual_clock; /* Actual HC clock rate */ + unsigned int slotno; /* used for sdio acpi binding */ + unsigned long private[0] ____cacheline_aligned; }; @@ -368,7 +369,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *); int mmc_add_host(struct mmc_host *); void mmc_remove_host(struct mmc_host *); void mmc_free_host(struct mmc_host *); -void mmc_of_parse(struct mmc_host *host); +int mmc_of_parse(struct mmc_host *host); static inline void *mmc_priv(struct mmc_host *host) { @@ -424,10 +425,6 @@ static inline int mmc_regulator_get_supply(struct mmc_host *mmc) } #endif -int mmc_card_awake(struct mmc_host *host); -int mmc_card_sleep(struct mmc_host *host); -int mmc_card_can_sleep(struct mmc_host *host); - int mmc_pm_notify(struct notifier_block *notify_block, unsigned long, void *); /* Module parameter */ diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index b838ffc49e4a..3e781b8c0be7 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -95,6 +95,9 @@ struct sdhci_host { /* The system physically doesn't support 1.8v, even if the host does */ #define SDHCI_QUIRK2_NO_1_8_V (1<<2) #define SDHCI_QUIRK2_PRESET_VALUE_BROKEN (1<<3) +#define SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON (1<<4) +/* Controller has a non-standard host control register */ +#define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ @@ -126,7 +129,7 @@ struct sdhci_host { #define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ #define SDHCI_PV_ENABLED (1<<8) /* Preset value enabled */ #define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ -#define SDHCI_HS200_NEEDS_TUNING (1<<10) /* HS200 needs tuning */ +#define SDHCI_SDR104_NEEDS_TUNING (1<<10) /* SDR104/HS200 needs tuning */ #define SDHCI_USING_RETUNING_TIMER (1<<11) /* Host is using a retuning timer for the card */ unsigned int version; /* SDHCI spec. version */ @@ -139,6 +142,7 @@ struct sdhci_host { u8 pwr; /* Current voltage */ bool runtime_suspended; /* Host is runtime suspended */ + bool bus_on; /* Bus power prevents runtime suspend */ struct mmc_request *mrq; /* Current request */ struct mmc_command *cmd; /* Current command */ @@ -167,6 +171,7 @@ struct sdhci_host { unsigned int ocr_avail_sdio; /* OCR bit masks */ unsigned int ocr_avail_sd; unsigned int ocr_avail_mmc; + u32 ocr_mask; /* available voltages */ wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */ unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */ diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h index e7d5dd67bb74..ccd8fb2cad52 100644 --- a/include/linux/mmc/sh_mmcif.h +++ b/include/linux/mmc/sh_mmcif.h @@ -16,7 +16,6 @@ #include <linux/io.h> #include <linux/platform_device.h> -#include <linux/sh_dma.h> /* * MMCIF : CE_CLK_CTRL [19:16] @@ -33,12 +32,12 @@ */ struct sh_mmcif_plat_data { - void (*set_pwr)(struct platform_device *pdev, int state); - void (*down_pwr)(struct platform_device *pdev); int (*get_cd)(struct platform_device *pdef); unsigned int slave_id_tx; /* embedded slave_id_[tr]x */ unsigned int slave_id_rx; bool use_cd_gpio : 1; + bool ccs_unsupported : 1; + bool clk_ctrl2_present : 1; unsigned int cd_gpio; u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */ unsigned long caps; @@ -62,6 +61,7 @@ struct sh_mmcif_plat_data { #define MMCIF_CE_INT_MASK 0x00000044 #define MMCIF_CE_HOST_STS1 0x00000048 #define MMCIF_CE_HOST_STS2 0x0000004C +#define MMCIF_CE_CLK_CTRL2 0x00000070 #define MMCIF_CE_VERSION 0x0000007C /* CE_BUF_ACC */ diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h index b76bcf0621f6..68927ae50845 100644 --- a/include/linux/mmc/sh_mobile_sdhi.h +++ b/include/linux/mmc/sh_mobile_sdhi.h @@ -25,8 +25,6 @@ struct sh_mobile_sdhi_info { unsigned long tmio_caps2; u32 tmio_ocr_mask; /* available MMC voltages */ unsigned int cd_gpio; - void (*set_pwr)(struct platform_device *pdev, int state); - int (*get_cd)(struct platform_device *pdev); /* callbacks for board specific setup code */ int (*init)(struct platform_device *pdev, diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h index 7d88d27bfafa..b0c73e4cacea 100644 --- a/include/linux/mmc/slot-gpio.h +++ b/include/linux/mmc/slot-gpio.h @@ -18,7 +18,8 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio); void mmc_gpio_free_ro(struct mmc_host *host); int mmc_gpio_get_cd(struct mmc_host *host); -int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio); +int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, + unsigned int debounce); void mmc_gpio_free_cd(struct mmc_host *host); #endif diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index ede274957e05..bd791e452ad7 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -105,6 +105,7 @@ struct zone_padding { enum zone_stat_item { /* First 128 byte cacheline (assuming 64 bit words) */ NR_FREE_PAGES, + NR_ALLOC_BATCH, NR_LRU_BASE, NR_INACTIVE_ANON = NR_LRU_BASE, /* must match order of LRU_[IN]ACTIVE */ NR_ACTIVE_ANON, /* " " " " " */ @@ -352,7 +353,6 @@ struct zone { * free areas of different sizes */ spinlock_t lock; - int all_unreclaimable; /* All pages pinned */ #if defined CONFIG_COMPACTION || defined CONFIG_CMA /* Set to true when the PG_migrate_skip bits should be cleared */ bool compact_blockskip_flush; @@ -450,7 +450,7 @@ struct zone { * * present_pages is physical pages existing within the zone, which * is calculated as: - * present_pages = spanned_pages - absent_pages(pags in holes); + * present_pages = spanned_pages - absent_pages(pages in holes); * * managed_pages is present pages managed by the buddy system, which * is calculated as (reserved_pages includes pages allocated by the @@ -474,10 +474,16 @@ struct zone { * frequently read in proximity to zone->lock. It's good to * give them a chance of being in the same cacheline. * - * Write access to present_pages and managed_pages at runtime should - * be protected by lock_memory_hotplug()/unlock_memory_hotplug(). - * Any reader who can't tolerant drift of present_pages and - * managed_pages should hold memory hotplug lock to get a stable value. + * Write access to present_pages at runtime should be protected by + * lock_memory_hotplug()/unlock_memory_hotplug(). Any reader who can't + * tolerant drift of present_pages should hold memory hotplug lock to + * get a stable value. + * + * Read access to managed_pages should be safe because it's unsigned + * long. Write access to zone->managed_pages and totalram_pages are + * protected by managed_page_count_lock at runtime. Idealy only + * adjust_managed_page_count() should be used instead of directly + * touching zone->managed_pages and totalram_pages. */ unsigned long spanned_pages; unsigned long present_pages; @@ -495,6 +501,13 @@ typedef enum { ZONE_CONGESTED, /* zone has many dirty pages backed by * a congested BDI */ + ZONE_TAIL_LRU_DIRTY, /* reclaim scanning has recently found + * many dirty file pages at the tail + * of the LRU. + */ + ZONE_WRITEBACK, /* reclaim scanning has recently found + * many pages under writeback + */ } zone_flags_t; static inline void zone_set_flag(struct zone *zone, zone_flags_t flag) @@ -517,6 +530,16 @@ static inline int zone_is_reclaim_congested(const struct zone *zone) return test_bit(ZONE_CONGESTED, &zone->flags); } +static inline int zone_is_reclaim_dirty(const struct zone *zone) +{ + return test_bit(ZONE_TAIL_LRU_DIRTY, &zone->flags); +} + +static inline int zone_is_reclaim_writeback(const struct zone *zone) +{ + return test_bit(ZONE_WRITEBACK, &zone->flags); +} + static inline int zone_is_reclaim_locked(const struct zone *zone) { return test_bit(ZONE_RECLAIM_LOCKED, &zone->flags); @@ -527,7 +550,7 @@ static inline int zone_is_oom_locked(const struct zone *zone) return test_bit(ZONE_OOM_LOCKED, &zone->flags); } -static inline unsigned zone_end_pfn(const struct zone *zone) +static inline unsigned long zone_end_pfn(const struct zone *zone) { return zone->zone_start_pfn + zone->spanned_pages; } @@ -716,7 +739,10 @@ typedef struct pglist_data { * or node_spanned_pages stay constant. Holding this will also * guarantee that any pfn_valid() stays that way. * - * Nests above zone->lock and zone->size_seqlock. + * pgdat_resize_lock() and pgdat_resize_unlock() are provided to + * manipulate node_size_lock without checking for CONFIG_MEMORY_HOTPLUG. + * + * Nests above zone->lock and zone->span_seqlock */ spinlock_t node_size_lock; #endif @@ -843,11 +869,6 @@ static inline int is_highmem_idx(enum zone_type idx) #endif } -static inline int is_normal_idx(enum zone_type idx) -{ - return (idx == ZONE_NORMAL); -} - /** * is_highmem - helper function to quickly check if a struct zone is a * highmem zone or not. This is an attempt to keep references @@ -866,29 +887,6 @@ static inline int is_highmem(struct zone *zone) #endif } -static inline int is_normal(struct zone *zone) -{ - return zone == zone->zone_pgdat->node_zones + ZONE_NORMAL; -} - -static inline int is_dma32(struct zone *zone) -{ -#ifdef CONFIG_ZONE_DMA32 - return zone == zone->zone_pgdat->node_zones + ZONE_DMA32; -#else - return 0; -#endif -} - -static inline int is_dma(struct zone *zone) -{ -#ifdef CONFIG_ZONE_DMA - return zone == zone->zone_pgdat->node_zones + ZONE_DMA; -#else - return 0; -#endif -} - /* These two functions are used to setup the per zone pages min values */ struct ctl_table; int min_free_kbytes_sysctl_handler(struct ctl_table *, int, @@ -1111,6 +1109,10 @@ struct mem_section { struct page_cgroup *page_cgroup; unsigned long pad; #endif + /* + * WARNING: mem_section must be a power-of-2 in size for the + * calculation and use of SECTION_ROOT_MASK to make sense. + */ }; #ifdef CONFIG_SPARSEMEM_EXTREME diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 779cf7c4a3d1..45e921401b06 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -9,6 +9,7 @@ #ifdef __KERNEL__ #include <linux/types.h> +#include <linux/uuid.h> typedef unsigned long kernel_ulong_t; #endif @@ -360,7 +361,8 @@ struct ssb_device_id { __u16 vendor; __u16 coreid; __u8 revision; -}; + __u8 __pad; +} __attribute__((packed, aligned(2))); #define SSB_DEVICE(_vendor, _coreid, _revision) \ { .vendor = _vendor, .coreid = _coreid, .revision = _revision, } #define SSB_DEVTABLE_END \ @@ -376,7 +378,7 @@ struct bcma_device_id { __u16 id; __u8 rev; __u8 class; -}; +} __attribute__((packed,aligned(2))); #define BCMA_CORE(_manuf, _id, _rev, _class) \ { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, } #define BCMA_CORETABLE_END \ @@ -455,7 +457,8 @@ enum dmi_field { }; struct dmi_strmatch { - unsigned char slot; + unsigned char slot:7; + unsigned char exact_match:1; char substr[79]; }; @@ -473,7 +476,8 @@ struct dmi_system_id { */ #define dmi_device_id dmi_system_id -#define DMI_MATCH(a, b) { a, b } +#define DMI_MATCH(a, b) { .slot = a, .substr = b } +#define DMI_EXACT_MATCH(a, b) { .slot = a, .substr = b, .exact_match = 1 } #define PLATFORM_NAME_SIZE 20 #define PLATFORM_MODULE_PREFIX "platform:" @@ -568,4 +572,31 @@ struct ipack_device_id { __u32 device; /* Device ID or IPACK_ANY_ID */ }; +#define MEI_CL_MODULE_PREFIX "mei:" +#define MEI_CL_NAME_SIZE 32 + +struct mei_cl_device_id { + char name[MEI_CL_NAME_SIZE]; + kernel_ulong_t driver_info; +}; + +/* RapidIO */ + +#define RIO_ANY_ID 0xffff + +/** + * struct rio_device_id - RIO device identifier + * @did: RapidIO device ID + * @vid: RapidIO vendor ID + * @asm_did: RapidIO assembly device ID + * @asm_vid: RapidIO assembly vendor ID + * + * Identifies a RapidIO device based on both the device/vendor IDs and + * the assembly device/vendor IDs. + */ +struct rio_device_id { + __u16 did, vid; + __u16 asm_did, asm_vid; +}; + #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/include/linux/module.h b/include/linux/module.h index ead1b5719a12..05f2447f8c15 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -42,6 +42,7 @@ struct module_kobject { struct module *mod; struct kobject *drivers_dir; struct module_param_attrs *mp; + struct completion *kobj_completion; }; struct module_attribute { @@ -97,6 +98,11 @@ extern const struct gtype##_id __mod_##gtype##_table \ /* For userspace: you can also call me... */ #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) +/* Soft module dependencies. See man modprobe.d for details. + * Example: MODULE_SOFTDEP("pre: module-foo module-bar post: module-baz") + */ +#define MODULE_SOFTDEP(_softdep) MODULE_INFO(softdep, _softdep) + /* * The following license idents are currently accepted as indicating free * software modules @@ -190,7 +196,7 @@ extern int modules_disabled; /* for sysctl */ /* Get/put a kernel symbol (calls must be symmetric) */ void *__symbol_get(const char *symbol); void *__symbol_get_gpl(const char *symbol); -#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) +#define symbol_get(x) ((typeof(&x))(__symbol_get(VMLINUX_SYMBOL_STR(x)))) /* modules using other modules: kdb wants to see this. */ struct module_use { @@ -453,7 +459,7 @@ extern void __module_put_and_exit(struct module *mod, long code) #ifdef CONFIG_MODULE_UNLOAD unsigned long module_refcount(struct module *mod); void __symbol_put(const char *symbol); -#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) +#define symbol_put(x) __symbol_put(VMLINUX_SYMBOL_STR(x)) void symbol_put_addr(void *addr); /* Sometimes we know we already have a refcount, and it's easier not diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 137b4198fc03..c3eb102a9cc8 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -36,7 +36,18 @@ static const char __UNIQUE_ID(name)[] \ struct kernel_param; +/* + * Flags available for kernel_param_ops + * + * NOARG - the parameter allows for no argument (foo instead of foo=1) + */ +enum { + KERNEL_PARAM_FL_NOARG = (1 << 0) +}; + struct kernel_param_ops { + /* How the ops should behave */ + unsigned int flags; /* Returns 0, or -errno. arg is in kp->arg. */ int (*set)(const char *val, const struct kernel_param *kp); /* Returns length written or -errno. Buffer is 4k (ie. be short!) */ @@ -187,7 +198,7 @@ struct kparam_array /* Obsolete - use module_param_cb() */ #define module_param_call(name, set, get, arg, perm) \ static struct kernel_param_ops __param_ops_##name = \ - { (void *)set, (void *)get }; \ + { 0, (void *)set, (void *)get }; \ __module_param_call(MODULE_PARAM_PREFIX, \ name, &__param_ops_##name, arg, \ (perm) + sizeof(__check_old_set_param(set))*0, -1) @@ -439,7 +450,7 @@ extern struct kernel_param_ops param_ops_string; extern int param_set_copystring(const char *val, const struct kernel_param *); extern int param_get_string(char *buffer, const struct kernel_param *kp); -/* for exporting parameters in /sys/parameters */ +/* for exporting parameters in /sys/module/.../parameters */ struct module; diff --git a/include/linux/mount.h b/include/linux/mount.h index d7029f4a191a..fdbb3e6aba65 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -47,6 +47,9 @@ struct mnt_namespace; #define MNT_INTERNAL 0x4000 +#define MNT_LOCK_READONLY 0x400000 +#define MNT_LOCKED 0x800000 + struct vfsmount { struct dentry *mnt_root; /* root of the mounted tree */ struct super_block *mnt_sb; /* pointer to superblock */ @@ -74,6 +77,6 @@ extern struct vfsmount *vfs_kern_mount(struct file_system_type *type, extern void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list); extern void mark_mounts_for_expiry(struct list_head *mounts); -extern dev_t name_to_dev_t(char *name); +extern dev_t name_to_dev_t(const char *name); #endif /* _LINUX_MOUNT_H */ diff --git a/include/linux/msi.h b/include/linux/msi.h index ce93a341337d..b17ead818aec 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -13,14 +13,14 @@ struct msi_msg { /* Helper functions */ struct irq_data; struct msi_desc; -extern void mask_msi_irq(struct irq_data *data); -extern void unmask_msi_irq(struct irq_data *data); -extern void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg); -extern void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg); -extern void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg); -extern void read_msi_msg(unsigned int irq, struct msi_msg *msg); -extern void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); -extern void write_msi_msg(unsigned int irq, struct msi_msg *msg); +void mask_msi_irq(struct irq_data *data); +void unmask_msi_irq(struct irq_data *data); +void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg); +void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg); +void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg); +void read_msi_msg(unsigned int irq, struct msi_msg *msg); +void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); +void write_msi_msg(unsigned int irq, struct msi_msg *msg); struct msi_desc { struct { @@ -35,6 +35,7 @@ struct msi_desc { u32 masked; /* mask bits */ unsigned int irq; + unsigned int nvec_used; /* number of messages */ struct list_head list; union { @@ -50,13 +51,31 @@ struct msi_desc { }; /* - * The arch hook for setup up msi irqs + * The arch hooks to setup up msi irqs. Those functions are + * implemented as weak symbols so that they /can/ be overriden by + * architecture specific code if needed. */ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); void arch_teardown_msi_irq(unsigned int irq); -extern int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); -extern void arch_teardown_msi_irqs(struct pci_dev *dev); -extern int arch_msi_check_device(struct pci_dev* dev, int nvec, int type); +int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); +void arch_teardown_msi_irqs(struct pci_dev *dev); +int arch_msi_check_device(struct pci_dev* dev, int nvec, int type); +void arch_restore_msi_irqs(struct pci_dev *dev, int irq); +void default_teardown_msi_irqs(struct pci_dev *dev); +void default_restore_msi_irqs(struct pci_dev *dev, int irq); + +struct msi_chip { + struct module *owner; + struct device *dev; + struct device_node *of_node; + struct list_head list; + + int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev, + struct msi_desc *desc); + void (*teardown_irq)(struct msi_chip *chip, unsigned int irq); + int (*check_device)(struct msi_chip *chip, struct pci_dev *dev, + int nvec, int type); +}; #endif /* LINUX_MSI_H */ diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h index 211ff67e8b0d..95fc482cef36 100644 --- a/include/linux/mtd/bbm.h +++ b/include/linux/mtd/bbm.h @@ -93,8 +93,6 @@ struct nand_bbt_descr { #define NAND_BBT_CREATE_EMPTY 0x00000400 /* Search good / bad pattern through all pages of a block */ #define NAND_BBT_SCANALLPAGES 0x00000800 -/* Scan block empty during good / bad block scan */ -#define NAND_BBT_SCANEMPTY 0x00001000 /* Write bbt if neccecary */ #define NAND_BBT_WRITE 0x00002000 /* Read and write back block contents when writing bbt */ diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h index 4eb0a50d0c55..e93837f647de 100644 --- a/include/linux/mtd/blktrans.h +++ b/include/linux/mtd/blktrans.h @@ -74,7 +74,7 @@ struct mtd_blktrans_ops { /* Called with mtd_table_mutex held; no race with add/remove */ int (*open)(struct mtd_blktrans_dev *dev); - int (*release)(struct mtd_blktrans_dev *dev); + void (*release)(struct mtd_blktrans_dev *dev); /* Called on {de,}registration and on subsequent addition/removal of devices, with mtd_table_mutex held. */ diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h index d6ed61ef451d..c8be32e9fc49 100644 --- a/include/linux/mtd/fsmc.h +++ b/include/linux/mtd/fsmc.h @@ -137,6 +137,7 @@ enum access_mode { /** * fsmc_nand_platform_data - platform specific NAND controller config + * @nand_timings: timing setup for the physical NAND interface * @partitions: partition table for the platform, use a default fallback * if this is NULL * @nr_partitions: the number of partitions in the previous entry diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index f9ac2897b86b..f9bfe526d310 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -173,6 +173,9 @@ struct mtd_info { /* ECC layout structure pointer - read only! */ struct nand_ecclayout *ecclayout; + /* the ecc step size. */ + unsigned int ecc_step_size; + /* max number of correctible bit errors per ecc step */ unsigned int ecc_strength; @@ -362,10 +365,10 @@ struct mtd_partition; struct mtd_part_parser_data; extern int mtd_device_parse_register(struct mtd_info *mtd, - const char **part_probe_types, - struct mtd_part_parser_data *parser_data, - const struct mtd_partition *defparts, - int defnr_parts); + const char * const *part_probe_types, + struct mtd_part_parser_data *parser_data, + const struct mtd_partition *defparts, + int defnr_parts); #define mtd_device_register(master, parts, nr_parts) \ mtd_device_parse_register(master, NULL, NULL, parts, nr_parts) extern int mtd_device_unregister(struct mtd_info *master); diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 7ccb3c59ed60..129548169400 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -56,7 +56,7 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); * is supported now. If you add a chip with bigger oobsize/page * adjust this accordingly. */ -#define NAND_MAX_OOBSIZE 640 +#define NAND_MAX_OOBSIZE 744 #define NAND_MAX_PAGESIZE 8192 /* @@ -86,7 +86,6 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); #define NAND_CMD_READOOB 0x50 #define NAND_CMD_ERASE1 0x60 #define NAND_CMD_STATUS 0x70 -#define NAND_CMD_STATUS_MULTI 0x71 #define NAND_CMD_SEQIN 0x80 #define NAND_CMD_RNDIN 0x85 #define NAND_CMD_READID 0x90 @@ -105,25 +104,6 @@ extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); #define NAND_CMD_RNDOUTSTART 0xE0 #define NAND_CMD_CACHEDPROG 0x15 -/* Extended commands for AG-AND device */ -/* - * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but - * there is no way to distinguish that from NAND_CMD_READ0 - * until the remaining sequence of commands has been completed - * so add a high order bit and mask it off in the command. - */ -#define NAND_CMD_DEPLETE1 0x100 -#define NAND_CMD_DEPLETE2 0x38 -#define NAND_CMD_STATUS_MULTI 0x71 -#define NAND_CMD_STATUS_ERROR 0x72 -/* multi-bank error status (banks 0-3) */ -#define NAND_CMD_STATUS_ERROR0 0x73 -#define NAND_CMD_STATUS_ERROR1 0x74 -#define NAND_CMD_STATUS_ERROR2 0x75 -#define NAND_CMD_STATUS_ERROR3 0x76 -#define NAND_CMD_STATUS_RESET 0x7f -#define NAND_CMD_STATUS_CLEAR 0xff - #define NAND_CMD_NONE -1 /* Status bits */ @@ -165,28 +145,15 @@ typedef enum { */ /* Buswidth is 16 bit */ #define NAND_BUSWIDTH_16 0x00000002 -/* Device supports partial programming without padding */ -#define NAND_NO_PADDING 0x00000004 /* Chip has cache program function */ #define NAND_CACHEPRG 0x00000008 -/* Chip has copy back function */ -#define NAND_COPYBACK 0x00000010 -/* - * AND Chip which has 4 banks and a confusing page / block - * assignment. See Renesas datasheet for further information. - */ -#define NAND_IS_AND 0x00000020 /* - * Chip has a array of 4 pages which can be read without - * additional ready /busy waits. + * Chip requires ready check on read (for auto-incremented sequential read). + * True only for small page devices; large page devices do not support + * autoincrement. */ -#define NAND_4PAGE_ARRAY 0x00000040 -/* - * Chip requires that BBT is periodically rewritten to prevent - * bits from adjacent blocks from 'leaking' in altering data. - * This happens with the Renesas AG-AND chips, possibly others. - */ -#define BBT_AUTO_REFRESH 0x00000080 +#define NAND_NEED_READRDY 0x00000100 + /* Chip does not allow subpage writes */ #define NAND_NO_SUBPAGE_WRITE 0x00000200 @@ -200,13 +167,10 @@ typedef enum { #define NAND_SUBPAGE_READ 0x00001000 /* Options valid for Samsung large page devices */ -#define NAND_SAMSUNG_LP_OPTIONS \ - (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK) +#define NAND_SAMSUNG_LP_OPTIONS NAND_CACHEPRG /* Macros to identify the above */ -#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING)) #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) -#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK)) #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ)) /* Non chip related options */ @@ -238,6 +202,10 @@ typedef enum { /* Keep gcc happy */ struct nand_chip; +/* ONFI features */ +#define ONFI_FEATURE_16_BIT_BUS (1 << 0) +#define ONFI_FEATURE_EXT_PARAM_PAGE (1 << 7) + /* ONFI timing mode, used in both asynchronous and synchronous mode */ #define ONFI_TIMING_MODE_0 (1 << 0) #define ONFI_TIMING_MODE_1 (1 << 1) @@ -253,6 +221,9 @@ struct nand_chip; /* ONFI subfeature parameters length */ #define ONFI_SUBFEATURE_PARAM_LEN 4 +/* ONFI optional commands SET/GET FEATURES supported? */ +#define ONFI_OPT_CMD_SET_GET_FEATURES (1 << 2) + struct nand_onfi_params { /* rev info and features block */ /* 'O' 'N' 'F' 'I' */ @@ -260,7 +231,10 @@ struct nand_onfi_params { __le16 revision; __le16 features; __le16 opt_cmd; - u8 reserved[22]; + u8 reserved0[2]; + __le16 ext_param_page_length; /* since ONFI 2.1 */ + u8 num_of_param_pages; /* since ONFI 2.1 */ + u8 reserved1[17]; /* manufacturer information block */ char manufacturer[12]; @@ -317,6 +291,40 @@ struct nand_onfi_params { #define ONFI_CRC_BASE 0x4F4E +/* Extended ECC information Block Definition (since ONFI 2.1) */ +struct onfi_ext_ecc_info { + u8 ecc_bits; + u8 codeword_size; + __le16 bb_per_lun; + __le16 block_endurance; + u8 reserved[2]; +} __packed; + +#define ONFI_SECTION_TYPE_0 0 /* Unused section. */ +#define ONFI_SECTION_TYPE_1 1 /* for additional sections. */ +#define ONFI_SECTION_TYPE_2 2 /* for ECC information. */ +struct onfi_ext_section { + u8 type; + u8 length; +} __packed; + +#define ONFI_EXT_SECTION_MAX 8 + +/* Extended Parameter Page Definition (since ONFI 2.1) */ +struct onfi_ext_param_page { + __le16 crc; + u8 sig[4]; /* 'E' 'P' 'P' 'S' */ + u8 reserved0[10]; + struct onfi_ext_section sections[ONFI_EXT_SECTION_MAX]; + + /* + * The actual size of the Extended Parameter Page is in + * @ext_param_page_length of nand_onfi_params{}. + * The following are the variable length sections. + * So we do not add any fields below. Please see the ONFI spec. + */ +} __packed; + /** * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices * @lock: protection lock @@ -354,6 +362,7 @@ struct nand_hw_control { * any single ECC step, 0 if bitflips uncorrectable, -EIO hw error * @read_subpage: function to read parts of the page covered by ECC; * returns same as read_page() + * @write_subpage: function to write parts of the page covered by ECC. * @write_page: function to write a page according to the ECC generator * requirements. * @write_oob_raw: function to write chip OOB data without ECC @@ -385,6 +394,9 @@ struct nand_ecc_ctrl { uint8_t *buf, int oob_required, int page); int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip, uint32_t offs, uint32_t len, uint8_t *buf); + int (*write_subpage)(struct mtd_info *mtd, struct nand_chip *chip, + uint32_t offset, uint32_t data_len, + const uint8_t *data_buf, int oob_required); int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t *buf, int oob_required); int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip, @@ -422,8 +434,8 @@ struct nand_buffers { * @write_buf: [REPLACEABLE] write data from the buffer to the chip * @read_buf: [REPLACEABLE] read data from the chip into the buffer * @select_chip: [REPLACEABLE] select chip nr - * @block_bad: [REPLACEABLE] check, if the block is bad - * @block_markbad: [REPLACEABLE] mark the block bad + * @block_bad: [REPLACEABLE] check if a block is bad, using OOB markers + * @block_markbad: [REPLACEABLE] mark a block bad * @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific function for controlling * ALE/CLE/nCE. Also used to write command and address * @init_size: [BOARDSPECIFIC] hardwarespecific function for setting @@ -466,6 +478,12 @@ struct nand_buffers { * bad block marker position; i.e., BBM == 11110111b is * not bad when badblockbits == 7 * @cellinfo: [INTERN] MLC/multichip data from chip ident + * @ecc_strength_ds: [INTERN] ECC correctability from the datasheet. + * Minimum amount of bit errors per @ecc_step_ds guaranteed + * to be correctable. If unknown, set to zero. + * @ecc_step_ds: [INTERN] ECC step required by the @ecc_strength_ds, + * also from the datasheet. It is the recommended ECC step + * size, if known; if unknown, set to zero. * @numchips: [INTERN] number of physical chips * @chipsize: [INTERN] the size of one chip for multichip arrays * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 @@ -480,7 +498,6 @@ struct nand_buffers { * supported, 0 otherwise. * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand - * @ecclayout: [REPLACEABLE] the default ECC placement scheme * @bbt: [INTERN] bad block table pointer * @bbt_td: [REPLACEABLE] bad block table descriptor for flash * lookup. @@ -520,8 +537,8 @@ struct nand_chip { int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page); int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, - const uint8_t *buf, int oob_required, int page, - int cached, int raw); + uint32_t offset, int data_len, const uint8_t *buf, + int oob_required, int page, int cached, int raw); int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip, int feature_addr, uint8_t *subfeature_para); int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip, @@ -542,6 +559,8 @@ struct nand_chip { unsigned int pagebuf_bitflips; int subpagesize; uint8_t cellinfo; + uint16_t ecc_strength_ds; + uint16_t ecc_step_ds; int badblockpos; int badblockbits; @@ -552,7 +571,6 @@ struct nand_chip { uint8_t *oob_poi; struct nand_hw_control *controller; - struct nand_ecclayout *ecclayout; struct nand_ecc_ctrl ecc; struct nand_buffers *buffers; @@ -582,25 +600,80 @@ struct nand_chip { #define NAND_MFR_MACRONIX 0xc2 #define NAND_MFR_EON 0x92 +/* The maximum expected count of bytes in the NAND ID sequence */ +#define NAND_MAX_ID_LEN 8 + +/* + * A helper for defining older NAND chips where the second ID byte fully + * defined the chip, including the geometry (chip size, eraseblock size, page + * size). All these chips have 512 bytes NAND page size. + */ +#define LEGACY_ID_NAND(nm, devid, chipsz, erasesz, opts) \ + { .name = (nm), {{ .dev_id = (devid) }}, .pagesize = 512, \ + .chipsize = (chipsz), .erasesize = (erasesz), .options = (opts) } + +/* + * A helper for defining newer chips which report their page size and + * eraseblock size via the extended ID bytes. + * + * The real difference between LEGACY_ID_NAND and EXTENDED_ID_NAND is that with + * EXTENDED_ID_NAND, manufacturers overloaded the same device ID so that the + * device ID now only represented a particular total chip size (and voltage, + * buswidth), and the page size, eraseblock size, and OOB size could vary while + * using the same device ID. + */ +#define EXTENDED_ID_NAND(nm, devid, chipsz, opts) \ + { .name = (nm), {{ .dev_id = (devid) }}, .chipsize = (chipsz), \ + .options = (opts) } + +#define NAND_ECC_INFO(_strength, _step) \ + { .strength_ds = (_strength), .step_ds = (_step) } +#define NAND_ECC_STRENGTH(type) ((type)->ecc.strength_ds) +#define NAND_ECC_STEP(type) ((type)->ecc.step_ds) + /** * struct nand_flash_dev - NAND Flash Device ID Structure - * @name: Identify the device type - * @id: device ID code - * @pagesize: Pagesize in bytes. Either 256 or 512 or 0 - * If the pagesize is 0, then the real pagesize - * and the eraseize are determined from the - * extended id bytes in the chip - * @erasesize: Size of an erase block in the flash device. - * @chipsize: Total chipsize in Mega Bytes - * @options: Bitfield to store chip relevant options + * @name: a human-readable name of the NAND chip + * @dev_id: the device ID (the second byte of the full chip ID array) + * @mfr_id: manufecturer ID part of the full chip ID array (refers the same + * memory address as @id[0]) + * @dev_id: device ID part of the full chip ID array (refers the same memory + * address as @id[1]) + * @id: full device ID array + * @pagesize: size of the NAND page in bytes; if 0, then the real page size (as + * well as the eraseblock size) is determined from the extended NAND + * chip ID array) + * @chipsize: total chip size in MiB + * @erasesize: eraseblock size in bytes (determined from the extended ID if 0) + * @options: stores various chip bit options + * @id_len: The valid length of the @id. + * @oobsize: OOB size + * @ecc.strength_ds: The ECC correctability from the datasheet, same as the + * @ecc_strength_ds in nand_chip{}. + * @ecc.step_ds: The ECC step required by the @ecc.strength_ds, same as the + * @ecc_step_ds in nand_chip{}, also from the datasheet. + * For example, the "4bit ECC for each 512Byte" can be set with + * NAND_ECC_INFO(4, 512). */ struct nand_flash_dev { char *name; - int id; - unsigned long pagesize; - unsigned long chipsize; - unsigned long erasesize; - unsigned long options; + union { + struct { + uint8_t mfr_id; + uint8_t dev_id; + }; + uint8_t id[NAND_MAX_ID_LEN]; + }; + unsigned int pagesize; + unsigned int chipsize; + unsigned int erasesize; + unsigned int options; + uint16_t id_len; + uint16_t oobsize; + struct { + uint16_t strength_ds; + uint16_t step_ds; + } ecc; }; /** @@ -617,8 +690,8 @@ extern struct nand_flash_dev nand_flash_ids[]; extern struct nand_manufacturers nand_manuf_ids[]; extern int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd); -extern int nand_update_bbt(struct mtd_info *mtd, loff_t offs); extern int nand_default_bbt(struct mtd_info *mtd); +extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs); extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt); extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, int allowbbt); @@ -700,6 +773,12 @@ struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd) return chip->priv; } +/* return the supported features. */ +static inline int onfi_feature(struct nand_chip *chip) +{ + return chip->onfi_version ? le16_to_cpu(chip->onfi_params.features) : 0; +} + /* return the supported asynchronous timing mode. */ static inline int onfi_get_async_timing_mode(struct nand_chip *chip) { diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h index d2887e76b7f6..aa6a2633c2da 100644 --- a/include/linux/mtd/physmap.h +++ b/include/linux/mtd/physmap.h @@ -30,7 +30,7 @@ struct physmap_flash_data { unsigned int pfow_base; char *probe_type; struct mtd_partition *parts; - const char **part_probe_types; + const char * const *part_probe_types; }; #endif /* __LINUX_MTD_PHYSMAP__ */ diff --git a/include/linux/mtd/plat-ram.h b/include/linux/mtd/plat-ram.h index e07890aff1cf..44212d65aa97 100644 --- a/include/linux/mtd/plat-ram.h +++ b/include/linux/mtd/plat-ram.h @@ -20,8 +20,8 @@ struct platdata_mtd_ram { const char *mapname; - const char **map_probes; - const char **probes; + const char * const *map_probes; + const char * const *probes; struct mtd_partition *partitions; int nr_partitions; int bankwidth; diff --git a/include/linux/mutex-debug.h b/include/linux/mutex-debug.h index 731d77d6e155..4ac8b1977b73 100644 --- a/include/linux/mutex-debug.h +++ b/include/linux/mutex-debug.h @@ -3,6 +3,7 @@ #include <linux/linkage.h> #include <linux/lockdep.h> +#include <linux/debug_locks.h> /* * Mutexes - debugging helpers: diff --git a/include/linux/mutex.h b/include/linux/mutex.h index 9121595a8ebf..ccd4260834c5 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -10,6 +10,7 @@ #ifndef __LINUX_MUTEX_H #define __LINUX_MUTEX_H +#include <asm/current.h> #include <linux/list.h> #include <linux/spinlock_types.h> #include <linux/linkage.h> @@ -53,6 +54,9 @@ struct mutex { #if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP) struct task_struct *owner; #endif +#ifdef CONFIG_MUTEX_SPIN_ON_OWNER + void *spin_mlock; /* Spinner MCS lock */ +#endif #ifdef CONFIG_DEBUG_MUTEXES const char *name; void *magic; @@ -133,6 +137,7 @@ static inline int mutex_is_locked(struct mutex *lock) #ifdef CONFIG_DEBUG_LOCK_ALLOC extern void mutex_lock_nested(struct mutex *lock, unsigned int subclass); extern void _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest_lock); + extern int __must_check mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass); extern int __must_check mutex_lock_killable_nested(struct mutex *lock, @@ -144,7 +149,7 @@ extern int __must_check mutex_lock_killable_nested(struct mutex *lock, #define mutex_lock_nest_lock(lock, nest_lock) \ do { \ - typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ + typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ _mutex_lock_nest_lock(lock, &(nest_lock)->dep_map); \ } while (0) @@ -167,6 +172,7 @@ extern int __must_check mutex_lock_killable(struct mutex *lock); */ extern int mutex_trylock(struct mutex *lock); extern void mutex_unlock(struct mutex *lock); + extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); #ifndef CONFIG_HAVE_ARCH_MUTEX_CPU_RELAX diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 49258e0ed1c6..61a0da38d0cb 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h @@ -6,6 +6,7 @@ #define __LINUX_MV643XX_ETH_H #include <linux/mbus.h> +#include <linux/if_ether.h> #define MV643XX_ETH_SHARED_NAME "mv643xx_eth" #define MV643XX_ETH_NAME "mv643xx_eth_port" @@ -19,7 +20,6 @@ struct mv643xx_eth_shared_platform_data { struct mbus_dram_target_info *dram; - struct platform_device *shared_smi; /* * Max packet size for Tx IP/Layer 4 checksum, when set to 0, default * limit of 9KiB will be used. @@ -31,6 +31,7 @@ struct mv643xx_eth_shared_platform_data { #define MV643XX_ETH_PHY_ADDR(x) (0x80 | (x)) #define MV643XX_ETH_PHY_NONE 0xff +struct device_node; struct mv643xx_eth_platform_data { /* * Pointer back to our parent instance, and our port number. @@ -42,12 +43,13 @@ struct mv643xx_eth_platform_data { * Whether a PHY is present, and if yes, at which address. */ int phy_addr; + struct device_node *phy_node; /* * Use this MAC address if it is valid, overriding the * address that is already in the hardware. */ - u8 mac_addr[6]; + u8 mac_addr[ETH_ALEN]; /* * If speed is 0, autonegotiation is enabled. diff --git a/include/linux/mxsfb.h b/include/linux/mxsfb.h deleted file mode 100644 index f14943d55315..000000000000 --- a/include/linux/mxsfb.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#ifndef __LINUX_MXSFB_H -#define __LINUX_MXSFB_H - -#include <linux/fb.h> - -#define STMLCDIF_8BIT 1 /** pixel data bus to the display is of 8 bit width */ -#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */ -#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */ -#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */ - -#define FB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6) -#define FB_SYNC_DOTCLK_FAILING_ACT (1 << 7) /* failing/negtive edge sampling */ - -struct mxsfb_platform_data { - struct fb_videomode *mode_list; - unsigned mode_count; - - unsigned default_bpp; - - unsigned dotclk_delay; /* refer manual HW_LCDIF_VDCTRL4 register */ - unsigned ld_intf_width; /* refer STMLCDIF_* macros */ - - unsigned fb_size; /* Size of the video memory. If zero a - * default will be used - */ - unsigned long fb_phys; /* physical address for the video memory. If - * zero the framebuffer memory will be dynamically - * allocated. If specified,fb_size must also be specified. - * fb_phys must be unused by Linux. - */ -}; - -#endif /* __LINUX_MXSFB_H */ diff --git a/include/linux/namei.h b/include/linux/namei.h index 5a5ff57ceed4..8e47bc7a1665 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -70,8 +70,7 @@ extern struct dentry *kern_path_create(int, const char *, struct path *, unsigne extern struct dentry *user_path_create(int, const char __user *, struct path *, unsigned int); extern void done_path_create(struct path *, struct dentry *); extern struct dentry *kern_path_locked(const char *, struct path *); -extern int vfs_path_lookup(struct dentry *, struct vfsmount *, - const char *, unsigned int, struct path *); +extern int kern_path_mountpoint(int, const char *, struct path *, unsigned int); extern struct dentry *lookup_one_len(const char *, struct dentry *, int); diff --git a/include/linux/nbd.h b/include/linux/nbd.h index 4871170a04a0..ae4981ebd18e 100644 --- a/include/linux/nbd.h +++ b/include/linux/nbd.h @@ -41,6 +41,7 @@ struct nbd_device { u64 bytesize; pid_t pid; /* pid of nbd-client, if attached */ int xmit_timeout; + int disconnect; /* a disconnect has been requested by user */ }; #endif diff --git a/include/linux/net.h b/include/linux/net.h index aa1673160a45..4f27575ce1d6 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -79,9 +79,9 @@ enum sock_type { #endif /* ARCH_HAS_SOCKET_TYPES */ enum sock_shutdown_cmd { - SHUT_RD = 0, - SHUT_WR = 1, - SHUT_RDWR = 2, + SHUT_RD, + SHUT_WR, + SHUT_RDWR, }; struct socket_wq { @@ -240,8 +240,8 @@ do { \ #define net_dbg_ratelimited(fmt, ...) \ net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__) -#define net_random() random32() -#define net_srandom(seed) srandom32((__force u32)seed) +#define net_random() prandom_u32() +#define net_srandom(seed) prandom_seed((__force u32)(seed)) extern int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t len); diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h index 3dd39340430e..a2a89a5c7be5 100644 --- a/include/linux/netdev_features.h +++ b/include/linux/netdev_features.h @@ -22,9 +22,9 @@ enum { NETIF_F_IPV6_CSUM_BIT, /* Can checksum TCP/UDP over IPV6 */ NETIF_F_HIGHDMA_BIT, /* Can DMA to high memory. */ NETIF_F_FRAGLIST_BIT, /* Scatter/gather IO. */ - NETIF_F_HW_VLAN_TX_BIT, /* Transmit VLAN hw acceleration */ - NETIF_F_HW_VLAN_RX_BIT, /* Receive VLAN hw acceleration */ - NETIF_F_HW_VLAN_FILTER_BIT, /* Receive filtering on VLAN */ + NETIF_F_HW_VLAN_CTAG_TX_BIT, /* Transmit VLAN CTAG HW acceleration */ + NETIF_F_HW_VLAN_CTAG_RX_BIT, /* Receive VLAN CTAG HW acceleration */ + NETIF_F_HW_VLAN_CTAG_FILTER_BIT,/* Receive filtering on VLAN CTAGs */ NETIF_F_VLAN_CHALLENGED_BIT, /* Device cannot handle VLAN packets */ NETIF_F_GSO_BIT, /* Enable software GSO. */ NETIF_F_LLTX_BIT, /* LockLess TX - deprecated. Please */ @@ -42,9 +42,10 @@ enum { NETIF_F_TSO6_BIT, /* ... TCPv6 segmentation */ NETIF_F_FSO_BIT, /* ... FCoE segmentation */ NETIF_F_GSO_GRE_BIT, /* ... GRE with TSO */ - /**/NETIF_F_GSO_LAST, /* [can't be last bit, see GSO_MASK] */ - NETIF_F_GSO_RESERVED2 /* ... free (fill GSO_MASK to 8 bits) */ - = NETIF_F_GSO_LAST, + NETIF_F_GSO_UDP_TUNNEL_BIT, /* ... UDP TUNNEL with TSO */ + NETIF_F_GSO_MPLS_BIT, /* ... MPLS segmentation */ + /**/NETIF_F_GSO_LAST = /* last bit, see GSO_MASK */ + NETIF_F_GSO_MPLS_BIT, NETIF_F_FCOE_CRC_BIT, /* FCoE CRC32 */ NETIF_F_SCTP_CSUM_BIT, /* SCTP checksum offload */ @@ -56,6 +57,9 @@ enum { NETIF_F_LOOPBACK_BIT, /* Enable loopback */ NETIF_F_RXFCS_BIT, /* Append FCS to skb pkt data */ NETIF_F_RXALL_BIT, /* Receive errored frames too */ + NETIF_F_HW_VLAN_STAG_TX_BIT, /* Transmit VLAN STAG HW acceleration */ + NETIF_F_HW_VLAN_STAG_RX_BIT, /* Receive VLAN STAG HW acceleration */ + NETIF_F_HW_VLAN_STAG_FILTER_BIT,/* Receive filtering on VLAN STAGs */ /* * Add your fresh new feature above and remember to update @@ -80,9 +84,9 @@ enum { #define NETIF_F_GSO_ROBUST __NETIF_F(GSO_ROBUST) #define NETIF_F_HIGHDMA __NETIF_F(HIGHDMA) #define NETIF_F_HW_CSUM __NETIF_F(HW_CSUM) -#define NETIF_F_HW_VLAN_FILTER __NETIF_F(HW_VLAN_FILTER) -#define NETIF_F_HW_VLAN_RX __NETIF_F(HW_VLAN_RX) -#define NETIF_F_HW_VLAN_TX __NETIF_F(HW_VLAN_TX) +#define NETIF_F_HW_VLAN_CTAG_FILTER __NETIF_F(HW_VLAN_CTAG_FILTER) +#define NETIF_F_HW_VLAN_CTAG_RX __NETIF_F(HW_VLAN_CTAG_RX) +#define NETIF_F_HW_VLAN_CTAG_TX __NETIF_F(HW_VLAN_CTAG_TX) #define NETIF_F_IP_CSUM __NETIF_F(IP_CSUM) #define NETIF_F_IPV6_CSUM __NETIF_F(IPV6_CSUM) #define NETIF_F_LLTX __NETIF_F(LLTX) @@ -102,7 +106,12 @@ enum { #define NETIF_F_VLAN_CHALLENGED __NETIF_F(VLAN_CHALLENGED) #define NETIF_F_RXFCS __NETIF_F(RXFCS) #define NETIF_F_RXALL __NETIF_F(RXALL) -#define NETIF_F_GRE_GSO __NETIF_F(GSO_GRE) +#define NETIF_F_GSO_GRE __NETIF_F(GSO_GRE) +#define NETIF_F_GSO_UDP_TUNNEL __NETIF_F(GSO_UDP_TUNNEL) +#define NETIF_F_GSO_MPLS __NETIF_F(GSO_MPLS) +#define NETIF_F_HW_VLAN_STAG_FILTER __NETIF_F(HW_VLAN_STAG_FILTER) +#define NETIF_F_HW_VLAN_STAG_RX __NETIF_F(HW_VLAN_STAG_RX) +#define NETIF_F_HW_VLAN_STAG_TX __NETIF_F(HW_VLAN_STAG_TX) /* Features valid for ethtool to change */ /* = all defined minus driver/device-class-related */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b3d00fa4b314..0ea606ffa7cd 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -144,8 +144,6 @@ static inline bool dev_xmit_complete(int rc) # else # define LL_MAX_HEADER 96 # endif -#elif IS_ENABLED(CONFIG_TR) -# define LL_MAX_HEADER 48 #else # define LL_MAX_HEADER 32 #endif @@ -210,9 +208,10 @@ struct netdev_hw_addr { #define NETDEV_HW_ADDR_T_SLAVE 3 #define NETDEV_HW_ADDR_T_UNICAST 4 #define NETDEV_HW_ADDR_T_MULTICAST 5 - bool synced; bool global_use; + int sync_cnt; int refcount; + int synced; struct rcu_head rcu_head; }; @@ -325,12 +324,15 @@ struct napi_struct { struct sk_buff *gro_list; struct sk_buff *skb; struct list_head dev_list; + struct hlist_node napi_hash_node; + unsigned int napi_id; }; enum { NAPI_STATE_SCHED, /* Poll is scheduled */ NAPI_STATE_DISABLE, /* Disable pending */ NAPI_STATE_NPSVC, /* Netpoll - don't dequeue from poll_list */ + NAPI_STATE_HASHED, /* In NAPI hash */ }; enum gro_result { @@ -447,6 +449,32 @@ extern void __napi_complete(struct napi_struct *n); extern void napi_complete(struct napi_struct *n); /** + * napi_by_id - lookup a NAPI by napi_id + * @napi_id: hashed napi_id + * + * lookup @napi_id in napi_hash table + * must be called under rcu_read_lock() + */ +extern struct napi_struct *napi_by_id(unsigned int napi_id); + +/** + * napi_hash_add - add a NAPI to global hashtable + * @napi: napi context + * + * generate a new napi_id and store a @napi under it in napi_hash + */ +extern void napi_hash_add(struct napi_struct *napi); + +/** + * napi_hash_del - remove a NAPI from global table + * @napi: napi context + * + * Warning: caller must observe rcu grace period + * before freeing memory containing @napi + */ +extern void napi_hash_del(struct napi_struct *napi); + +/** * napi_disable - prevent NAPI from scheduling * @n: napi context * @@ -594,7 +622,6 @@ struct rps_dev_flow { struct rps_dev_flow_table { unsigned int mask; struct rcu_head rcu; - struct work_struct free_work; struct rps_dev_flow flows[0]; }; #define RPS_DEV_FLOW_TABLE_SIZE(_num) (sizeof(struct rps_dev_flow_table) + \ @@ -701,6 +728,16 @@ struct netdev_fcoe_hbainfo { }; #endif +#define MAX_PHYS_PORT_ID_LEN 32 + +/* This structure holds a unique identifier to identify the + * physical port used by a netdevice. + */ +struct netdev_phys_port_id { + unsigned char id[MAX_PHYS_PORT_ID_LEN]; + unsigned char id_len; +}; + /* * This structure defines the management hooks for network devices. * The following hooks can be defined; unless noted otherwise, they are @@ -785,13 +822,13 @@ struct netdev_fcoe_hbainfo { * 3. Update dev->stats asynchronously and atomically, and define * neither operation. * - * int (*ndo_vlan_rx_add_vid)(struct net_device *dev, unsigned short vid); - * If device support VLAN filtering (dev->features & NETIF_F_HW_VLAN_FILTER) - * this function is called when a VLAN id is registered. + * int (*ndo_vlan_rx_add_vid)(struct net_device *dev, __be16 proto, u16t vid); + * If device support VLAN filtering this function is called when a + * VLAN id is registered. * * int (*ndo_vlan_rx_kill_vid)(struct net_device *dev, unsigned short vid); - * If device support VLAN filtering (dev->features & NETIF_F_HW_VLAN_FILTER) - * this function is called when a VLAN id is unregistered. + * If device support VLAN filtering this function is called when a + * VLAN id is unregistered. * * void (*ndo_poll_controller)(struct net_device *dev); * @@ -802,6 +839,7 @@ struct netdev_fcoe_hbainfo { * int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting); * int (*ndo_get_vf_config)(struct net_device *dev, * int vf, struct ifla_vf_info *ivf); + * int (*ndo_set_vf_link_state)(struct net_device *dev, int vf, int link_state); * int (*ndo_set_vf_port)(struct net_device *dev, int vf, * struct nlattr *port[]); * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb); @@ -895,7 +933,7 @@ struct netdev_fcoe_hbainfo { * * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh) * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq, - * struct net_device *dev) + * struct net_device *dev, u32 filter_mask) * * int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier); * Called to change device carrier. Soft-devices (like dummy, team, etc) @@ -904,6 +942,25 @@ struct netdev_fcoe_hbainfo { * that determine carrier state from physical hardware properties (eg * network cables) or protocol-dependent mechanisms (eg * USB_CDC_NOTIFY_NETWORK_CONNECTION) should NOT implement this function. + * + * int (*ndo_get_phys_port_id)(struct net_device *dev, + * struct netdev_phys_port_id *ppid); + * Called to get ID of physical port of this device. If driver does + * not implement this, it is assumed that the hw is not able to have + * multiple net devices on single physical port. + * + * void (*ndo_add_vxlan_port)(struct net_device *dev, + * sa_family_t sa_family, __be16 port); + * Called by vxlan to notiy a driver about the UDP port and socket + * address family that vxlan is listnening to. It is called only when + * a new port starts listening. The operation is protected by the + * vxlan_net->sock_lock. + * + * void (*ndo_del_vxlan_port)(struct net_device *dev, + * sa_family_t sa_family, __be16 port); + * Called by vxlan to notify the driver about a UDP port and socket + * address family that vxlan is not listening to anymore. The operation + * is protected by the vxlan_net->sock_lock. */ struct net_device_ops { int (*ndo_init)(struct net_device *dev); @@ -935,9 +992,9 @@ struct net_device_ops { struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); int (*ndo_vlan_rx_add_vid)(struct net_device *dev, - unsigned short vid); + __be16 proto, u16 vid); int (*ndo_vlan_rx_kill_vid)(struct net_device *dev, - unsigned short vid); + __be16 proto, u16 vid); #ifdef CONFIG_NET_POLL_CONTROLLER void (*ndo_poll_controller)(struct net_device *dev); int (*ndo_netpoll_setup)(struct net_device *dev, @@ -945,6 +1002,9 @@ struct net_device_ops { gfp_t gfp); void (*ndo_netpoll_cleanup)(struct net_device *dev); #endif +#ifdef CONFIG_NET_RX_BUSY_POLL + int (*ndo_busy_poll)(struct napi_struct *dev); +#endif int (*ndo_set_vf_mac)(struct net_device *dev, int queue, u8 *mac); int (*ndo_set_vf_vlan)(struct net_device *dev, @@ -956,6 +1016,8 @@ struct net_device_ops { int (*ndo_get_vf_config)(struct net_device *dev, int vf, struct ifla_vf_info *ivf); + int (*ndo_set_vf_link_state)(struct net_device *dev, + int vf, int link_state); int (*ndo_set_vf_port)(struct net_device *dev, int vf, struct nlattr *port[]); @@ -1027,6 +1089,14 @@ struct net_device_ops { struct nlmsghdr *nlh); int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier); + int (*ndo_get_phys_port_id)(struct net_device *dev, + struct netdev_phys_port_id *ppid); + void (*ndo_add_vxlan_port)(struct net_device *dev, + sa_family_t sa_family, + __be16 port); + void (*ndo_del_vxlan_port)(struct net_device *dev, + sa_family_t sa_family, + __be16 port); }; /* @@ -1074,6 +1144,19 @@ struct net_device { struct list_head napi_list; struct list_head unreg_list; + /* directly linked devices, like slaves for bonding */ + struct { + struct list_head upper; + struct list_head lower; + } adj_list; + + /* all linked devices, *including* neighbours */ + struct { + struct list_head upper; + struct list_head lower; + } all_adj_list; + + /* currently active device features */ netdev_features_t features; /* user-changeable features */ @@ -1088,6 +1171,8 @@ struct net_device { * need to set them appropriately. */ netdev_features_t hw_enc_features; + /* mask of fetures inheritable by MPLS */ + netdev_features_t mpls_features; /* Interface index. Unique device identifier */ int ifindex; @@ -1140,11 +1225,20 @@ struct net_device { unsigned char addr_assign_type; /* hw address assignment type */ unsigned char addr_len; /* hardware address length */ unsigned char neigh_priv_len; - unsigned short dev_id; /* for shared network cards */ - + unsigned short dev_id; /* Used to differentiate devices + * that share the same link + * layer address + */ spinlock_t addr_list_lock; struct netdev_hw_addr_list uc; /* Unicast mac addresses */ struct netdev_hw_addr_list mc; /* Multicast mac addresses */ + struct netdev_hw_addr_list dev_addrs; /* list of device + * hw addresses + */ +#ifdef CONFIG_SYSFS + struct kset *queues_kset; +#endif + bool uc_promisc; unsigned int promiscuity; unsigned int allmulti; @@ -1177,21 +1271,11 @@ struct net_device { * avoid dirtying this cache line. */ - struct list_head upper_dev_list; /* List of upper devices */ - /* Interface address info used in eth_type_trans() */ unsigned char *dev_addr; /* hw address, (before bcast because most packets are unicast) */ - struct netdev_hw_addr_list dev_addrs; /* list of device - hw addresses */ - - unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ - -#ifdef CONFIG_SYSFS - struct kset *queues_kset; -#endif #ifdef CONFIG_RPS struct netdev_rx_queue *_rx; @@ -1202,18 +1286,14 @@ struct net_device { /* Number of RX queues currently active in device */ unsigned int real_num_rx_queues; -#ifdef CONFIG_RFS_ACCEL - /* CPU reverse-mapping for RX completion interrupts, indexed - * by RX queue number. Assigned by driver. This must only be - * set if the ndo_rx_flow_steer operation is defined. */ - struct cpu_rmap *rx_cpu_rmap; -#endif #endif rx_handler_func_t __rcu *rx_handler; void __rcu *rx_handler_data; struct netdev_queue __rcu *ingress_queue; + unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ + /* * Cache lines mostly used on transmit path @@ -1235,6 +1315,12 @@ struct net_device { #ifdef CONFIG_XPS struct xps_dev_maps __rcu *xps_maps; #endif +#ifdef CONFIG_RFS_ACCEL + /* CPU reverse-mapping for RX completion interrupts, indexed + * by RX queue number. Assigned by driver. This must only be + * set if the ndo_rx_flow_steer operation is defined. */ + struct cpu_rmap *rx_cpu_rmap; +#endif /* These may be needed for future network-power-down code. */ @@ -1475,6 +1561,11 @@ static inline void *netdev_priv(const struct net_device *dev) */ #define SET_NETDEV_DEVTYPE(net, devtype) ((net)->dev.type = (devtype)) +/* Default NAPI poll() weight + * Device drivers are strongly advised to not use bigger value + */ +#define NAPI_POLL_WEIGHT 64 + /** * netif_napi_add - initialize a napi context * @dev: network device @@ -1589,16 +1680,39 @@ struct packet_offload { #define NETDEV_RELEASE 0x0012 #define NETDEV_NOTIFY_PEERS 0x0013 #define NETDEV_JOIN 0x0014 +#define NETDEV_CHANGEUPPER 0x0015 +#define NETDEV_RESEND_IGMP 0x0016 extern int register_netdevice_notifier(struct notifier_block *nb); extern int unregister_netdevice_notifier(struct notifier_block *nb); -extern int call_netdevice_notifiers(unsigned long val, struct net_device *dev); +struct netdev_notifier_info { + struct net_device *dev; +}; -extern rwlock_t dev_base_lock; /* Device list lock */ +struct netdev_notifier_change_info { + struct netdev_notifier_info info; /* must be first */ + unsigned int flags_changed; +}; -extern seqcount_t devnet_rename_seq; /* Device rename seq */ +static inline void netdev_notifier_info_init(struct netdev_notifier_info *info, + struct net_device *dev) +{ + info->dev = dev; +} +static inline struct net_device * +netdev_notifier_info_to_dev(const struct netdev_notifier_info *info) +{ + return info->dev; +} + +extern int call_netdevice_notifiers_info(unsigned long val, struct net_device *dev, + struct netdev_notifier_info *info); +extern int call_netdevice_notifiers(unsigned long val, struct net_device *dev); + + +extern rwlock_t dev_base_lock; /* Device list lock */ #define for_each_netdev(net, d) \ list_for_each_entry(d, &(net)->dev_base_head, dev_list) @@ -1612,6 +1726,9 @@ extern seqcount_t devnet_rename_seq; /* Device rename seq */ list_for_each_entry_continue(d, &(net)->dev_base_head, dev_list) #define for_each_netdev_continue_rcu(net, d) \ list_for_each_entry_continue_rcu(d, &(net)->dev_base_head, dev_list) +#define for_each_netdev_in_bond_rcu(bond, slave) \ + for_each_netdev_rcu(&init_net, slave) \ + if (netdev_master_upper_dev_get_rcu(slave) == bond) #define net_device_entry(lh) list_entry(lh, struct net_device, dev_list) static inline struct net_device *next_net_device(struct net_device *dev) @@ -1684,11 +1801,11 @@ extern int netdev_refcnt_read(const struct net_device *dev); extern void free_netdev(struct net_device *dev); extern void synchronize_net(void); extern int init_dummy_netdev(struct net_device *dev); -extern void netdev_resync_ops(struct net_device *dev); extern struct net_device *dev_get_by_index(struct net *net, int ifindex); extern struct net_device *__dev_get_by_index(struct net *net, int ifindex); extern struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex); +extern int netdev_get_name(struct net *net, char *name, int ifindex); extern int dev_restart(struct net_device *dev); #ifdef CONFIG_NETPOLL_TRAP extern int netpoll_trap(void); @@ -1772,6 +1889,19 @@ static inline int unregister_gifconf(unsigned int family) return register_gifconf(family, NULL); } +#ifdef CONFIG_NET_FLOW_LIMIT +#define FLOW_LIMIT_HISTORY (1 << 7) /* must be ^2 and !overflow buckets */ +struct sd_flow_limit { + u64 count; + unsigned int num_buckets; + unsigned int history_head; + u16 history[FLOW_LIMIT_HISTORY]; + u8 buckets[]; +}; + +extern int netdev_flow_limit_table_len; +#endif /* CONFIG_NET_FLOW_LIMIT */ + /* * Incoming packets are placed on per-cpu queues */ @@ -1801,6 +1931,10 @@ struct softnet_data { unsigned int dropped; struct sk_buff_head input_pkt_queue; struct napi_struct backlog; + +#ifdef CONFIG_NET_FLOW_LIMIT + struct sd_flow_limit __rcu *flow_limit; +#endif }; static inline void input_queue_head_incr(struct softnet_data *sd) @@ -1977,6 +2111,15 @@ static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue, #endif } +/** + * netdev_sent_queue - report the number of bytes queued to hardware + * @dev: network device + * @bytes: number of bytes queued to the hardware device queue + * + * Report the number of bytes queued for sending/completion to the network + * device hardware queue. @bytes should be a good approximation and should + * exactly match netdev_completed_queue() @bytes + */ static inline void netdev_sent_queue(struct net_device *dev, unsigned int bytes) { netdev_tx_sent_queue(netdev_get_tx_queue(dev, 0), bytes); @@ -2006,6 +2149,16 @@ static inline void netdev_tx_completed_queue(struct netdev_queue *dev_queue, #endif } +/** + * netdev_completed_queue - report bytes and packets completed by device + * @dev: network device + * @pkts: actual number of packets sent over the medium + * @bytes: actual number of bytes sent over the medium + * + * Report the number of bytes and packets transmitted by the network device + * hardware queue over the physical medium, @bytes must exactly match the + * @bytes amount passed to netdev_sent_queue() + */ static inline void netdev_completed_queue(struct net_device *dev, unsigned int pkts, unsigned int bytes) { @@ -2020,6 +2173,13 @@ static inline void netdev_tx_reset_queue(struct netdev_queue *q) #endif } +/** + * netdev_reset_queue - reset the packets and bytes count of a network device + * @dev_queue: network device + * + * Reset the bytes and packet count of a network device and clear the + * software flow control OFF bit for this network device + */ static inline void netdev_reset_queue(struct net_device *dev_queue) { netdev_tx_reset_queue(netdev_get_tx_queue(dev_queue, 0)); @@ -2229,6 +2389,8 @@ extern int dev_set_mac_address(struct net_device *, struct sockaddr *); extern int dev_change_carrier(struct net_device *, bool new_carrier); +extern int dev_get_phys_port_id(struct net_device *dev, + struct netdev_phys_port_id *ppid); extern int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, struct netdev_queue *txq); @@ -2621,6 +2783,7 @@ extern int dev_uc_add(struct net_device *dev, const unsigned char *addr); extern int dev_uc_add_excl(struct net_device *dev, const unsigned char *addr); extern int dev_uc_del(struct net_device *dev, const unsigned char *addr); extern int dev_uc_sync(struct net_device *to, struct net_device *from); +extern int dev_uc_sync_multiple(struct net_device *to, struct net_device *from); extern void dev_uc_unsync(struct net_device *to, struct net_device *from); extern void dev_uc_flush(struct net_device *dev); extern void dev_uc_init(struct net_device *dev); @@ -2632,6 +2795,7 @@ extern int dev_mc_add_excl(struct net_device *dev, const unsigned char *addr); extern int dev_mc_del(struct net_device *dev, const unsigned char *addr); extern int dev_mc_del_global(struct net_device *dev, const unsigned char *addr); extern int dev_mc_sync(struct net_device *to, struct net_device *from); +extern int dev_mc_sync_multiple(struct net_device *to, struct net_device *from); extern void dev_mc_unsync(struct net_device *to, struct net_device *from); extern void dev_mc_flush(struct net_device *dev); extern void dev_mc_init(struct net_device *dev); @@ -2659,14 +2823,49 @@ extern int bpf_jit_enable; extern bool netdev_has_upper_dev(struct net_device *dev, struct net_device *upper_dev); extern bool netdev_has_any_upper_dev(struct net_device *dev); +extern struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev, + struct list_head **iter); + +/* iterate through upper list, must be called under RCU read lock */ +#define netdev_for_each_all_upper_dev_rcu(dev, updev, iter) \ + for (iter = &(dev)->all_adj_list.upper, \ + updev = netdev_all_upper_get_next_dev_rcu(dev, &(iter)); \ + updev; \ + updev = netdev_all_upper_get_next_dev_rcu(dev, &(iter))) + +extern void *netdev_lower_get_next_private(struct net_device *dev, + struct list_head **iter); +extern void *netdev_lower_get_next_private_rcu(struct net_device *dev, + struct list_head **iter); + +#define netdev_for_each_lower_private(dev, priv, iter) \ + for (iter = (dev)->adj_list.lower.next, \ + priv = netdev_lower_get_next_private(dev, &(iter)); \ + priv; \ + priv = netdev_lower_get_next_private(dev, &(iter))) + +#define netdev_for_each_lower_private_rcu(dev, priv, iter) \ + for (iter = &(dev)->adj_list.lower, \ + priv = netdev_lower_get_next_private_rcu(dev, &(iter)); \ + priv; \ + priv = netdev_lower_get_next_private_rcu(dev, &(iter))) + +extern void *netdev_adjacent_get_private(struct list_head *adj_list); extern struct net_device *netdev_master_upper_dev_get(struct net_device *dev); extern struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev); extern int netdev_upper_dev_link(struct net_device *dev, struct net_device *upper_dev); extern int netdev_master_upper_dev_link(struct net_device *dev, struct net_device *upper_dev); +extern int netdev_master_upper_dev_link_private(struct net_device *dev, + struct net_device *upper_dev, + void *private); extern void netdev_upper_dev_unlink(struct net_device *dev, struct net_device *upper_dev); +extern void *netdev_lower_dev_get_private_rcu(struct net_device *dev, + struct net_device *lower_dev); +extern void *netdev_lower_dev_get_private(struct net_device *dev, + struct net_device *lower_dev); extern int skb_checksum_help(struct sk_buff *skb); extern struct sk_buff *__skb_gso_segment(struct sk_buff *skb, netdev_features_t features, bool tx_path); @@ -2678,6 +2877,19 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, netdev_features_t features) { return __skb_gso_segment(skb, features, true); } +__be16 skb_network_protocol(struct sk_buff *skb); + +static inline bool can_checksum_protocol(netdev_features_t features, + __be16 protocol) +{ + return ((features & NETIF_F_GEN_CSUM) || + ((features & NETIF_F_V4_CSUM) && + protocol == htons(ETH_P_IP)) || + ((features & NETIF_F_V6_CSUM) && + protocol == htons(ETH_P_IPV6)) || + ((features & NETIF_F_FCOE_CRC) && + protocol == htons(ETH_P_FCOE))); +} #ifdef CONFIG_BUG extern void netdev_rx_csum_fault(struct net_device *dev); @@ -2696,8 +2908,20 @@ extern int __init dev_proc_init(void); #define dev_proc_init() 0 #endif -extern int netdev_class_create_file(struct class_attribute *class_attr); -extern void netdev_class_remove_file(struct class_attribute *class_attr); +extern int netdev_class_create_file_ns(struct class_attribute *class_attr, + const void *ns); +extern void netdev_class_remove_file_ns(struct class_attribute *class_attr, + const void *ns); + +static inline int netdev_class_create_file(struct class_attribute *class_attr) +{ + return netdev_class_create_file_ns(class_attr, NULL); +} + +static inline void netdev_class_remove_file(struct class_attribute *class_attr) +{ + netdev_class_remove_file_ns(class_attr, NULL); +} extern struct kobj_ns_type_operations net_ns_type_operations; @@ -2712,6 +2936,17 @@ static inline netdev_features_t netdev_get_wanted_features( } netdev_features_t netdev_increment_features(netdev_features_t all, netdev_features_t one, netdev_features_t mask); + +/* Allow TSO being used on stacked device : + * Performing the GSO segmentation before last device + * is a performance improvement. + */ +static inline netdev_features_t netdev_add_tso_features(netdev_features_t features, + netdev_features_t mask) +{ + return netdev_increment_features(features, NETIF_F_ALL_TSO, mask); +} + int __netdev_update_features(struct net_device *dev); void netdev_update_features(struct net_device *dev); void netdev_change_features(struct net_device *dev); @@ -2756,6 +2991,11 @@ static inline void netif_set_gso_max_size(struct net_device *dev, dev->gso_max_size = size; } +static inline bool netif_is_bond_master(struct net_device *dev) +{ + return dev->flags & IFF_MASTER && dev->priv_flags & IFF_BONDING; +} + static inline bool netif_is_bond_slave(struct net_device *dev) { return dev->flags & IFF_SLAVE && dev->priv_flags & IFF_BONDING; diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index ee142846f56a..708fe72ab913 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -35,7 +35,7 @@ static inline void nf_inet_addr_mask(const union nf_inet_addr *a1, result->all[3] = a1->all[3] & mask->all[3]; } -extern void netfilter_init(void); +extern int netfilter_init(void); /* Largest hook number + 1 */ #define NF_MAX_HOOKS 8 @@ -289,11 +289,6 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family) #endif } -#ifdef CONFIG_PROC_FS -#include <linux/proc_fs.h> -extern struct proc_dir_entry *proc_net_netfilter; -#endif - #else /* !CONFIG_NETFILTER */ #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) #define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb) @@ -319,25 +314,24 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family) #endif /*CONFIG_NETFILTER*/ #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) -extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *) __rcu; -extern void nf_ct_attach(struct sk_buff *, struct sk_buff *); +extern void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *) __rcu; +extern void nf_ct_attach(struct sk_buff *, const struct sk_buff *); extern void (*nf_ct_destroy)(struct nf_conntrack *) __rcu; struct nf_conn; +enum ip_conntrack_info; struct nlattr; struct nfq_ct_hook { size_t (*build_size)(const struct nf_conn *ct); int (*build)(struct sk_buff *skb, struct nf_conn *ct); int (*parse)(const struct nlattr *attr, struct nf_conn *ct); -}; -extern struct nfq_ct_hook __rcu *nfq_ct_hook; - -struct nfq_ct_nat_hook { + int (*attach_expect)(const struct nlattr *attr, struct nf_conn *ct, + u32 portid, u32 report); void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct, - u32 ctinfo, int off); + enum ip_conntrack_info ctinfo, s32 off); }; -extern struct nfq_ct_nat_hook __rcu *nfq_ct_nat_hook; +extern struct nfq_ct_hook __rcu *nfq_ct_hook; #else static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} #endif diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h index 7958e84a65af..9ac9fbde7b61 100644 --- a/include/linux/netfilter/ipset/ip_set.h +++ b/include/linux/netfilter/ipset/ip_set.h @@ -1,7 +1,7 @@ /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> * Patrick Schaaf <bof@bof.de> * Martin Josefsson <gandalf@wlug.westbo.se> - * Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> + * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> * * 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 @@ -47,10 +47,36 @@ enum ip_set_feature { IPSET_DUMP_LAST = (1 << IPSET_DUMP_LAST_FLAG), }; +/* Set extensions */ +enum ip_set_extension { + IPSET_EXT_NONE = 0, + IPSET_EXT_BIT_TIMEOUT = 1, + IPSET_EXT_TIMEOUT = (1 << IPSET_EXT_BIT_TIMEOUT), + IPSET_EXT_BIT_COUNTER = 2, + IPSET_EXT_COUNTER = (1 << IPSET_EXT_BIT_COUNTER), +}; + +/* Extension offsets */ +enum ip_set_offset { + IPSET_OFFSET_TIMEOUT = 0, + IPSET_OFFSET_COUNTER, + IPSET_OFFSET_MAX, +}; + +#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT) +#define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER) + +struct ip_set_ext { + unsigned long timeout; + u64 packets; + u64 bytes; +}; + struct ip_set; typedef int (*ipset_adtfn)(struct ip_set *set, void *value, - u32 timeout, u32 flags); + const struct ip_set_ext *ext, + struct ip_set_ext *mext, u32 cmdflags); /* Kernel API function options */ struct ip_set_adt_opt { @@ -58,7 +84,7 @@ struct ip_set_adt_opt { u8 dim; /* Dimension of match/target */ u8 flags; /* Direction and negation flags */ u32 cmdflags; /* Command-like flags */ - u32 timeout; /* Timeout value */ + struct ip_set_ext ext; /* Extensions */ }; /* Set type, variant-specific part */ @@ -69,7 +95,7 @@ struct ip_set_type_variant { * positive for matching element */ int (*kadt)(struct ip_set *set, const struct sk_buff *skb, const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt); + enum ipset_adt adt, struct ip_set_adt_opt *opt); /* Userspace: test/add/del entries * returns negative error code, @@ -151,10 +177,76 @@ struct ip_set { u8 family; /* The type revision */ u8 revision; + /* Extensions */ + u8 extensions; /* The type specific data */ void *data; }; +struct ip_set_counter { + atomic64_t bytes; + atomic64_t packets; +}; + +static inline void +ip_set_add_bytes(u64 bytes, struct ip_set_counter *counter) +{ + atomic64_add((long long)bytes, &(counter)->bytes); +} + +static inline void +ip_set_add_packets(u64 packets, struct ip_set_counter *counter) +{ + atomic64_add((long long)packets, &(counter)->packets); +} + +static inline u64 +ip_set_get_bytes(const struct ip_set_counter *counter) +{ + return (u64)atomic64_read(&(counter)->bytes); +} + +static inline u64 +ip_set_get_packets(const struct ip_set_counter *counter) +{ + return (u64)atomic64_read(&(counter)->packets); +} + +static inline void +ip_set_update_counter(struct ip_set_counter *counter, + const struct ip_set_ext *ext, + struct ip_set_ext *mext, u32 flags) +{ + if (ext->packets != ULLONG_MAX && + !(flags & IPSET_FLAG_SKIP_COUNTER_UPDATE)) { + ip_set_add_bytes(ext->bytes, counter); + ip_set_add_packets(ext->packets, counter); + } + if (flags & IPSET_FLAG_MATCH_COUNTERS) { + mext->packets = ip_set_get_packets(counter); + mext->bytes = ip_set_get_bytes(counter); + } +} + +static inline bool +ip_set_put_counter(struct sk_buff *skb, struct ip_set_counter *counter) +{ + return nla_put_net64(skb, IPSET_ATTR_BYTES, + cpu_to_be64(ip_set_get_bytes(counter))) || + nla_put_net64(skb, IPSET_ATTR_PACKETS, + cpu_to_be64(ip_set_get_packets(counter))); +} + +static inline void +ip_set_init_counter(struct ip_set_counter *counter, + const struct ip_set_ext *ext) +{ + if (ext->bytes != ULLONG_MAX) + atomic64_set(&(counter)->bytes, (long long)(ext->bytes)); + if (ext->packets != ULLONG_MAX) + atomic64_set(&(counter)->packets, (long long)(ext->packets)); +} + /* register and unregister set references */ extern ip_set_id_t ip_set_get_byname(const char *name, struct ip_set **set); extern void ip_set_put_byindex(ip_set_id_t index); @@ -167,19 +259,21 @@ extern void ip_set_nfnl_put(ip_set_id_t index); extern int ip_set_add(ip_set_id_t id, const struct sk_buff *skb, const struct xt_action_param *par, - const struct ip_set_adt_opt *opt); + struct ip_set_adt_opt *opt); extern int ip_set_del(ip_set_id_t id, const struct sk_buff *skb, const struct xt_action_param *par, - const struct ip_set_adt_opt *opt); + struct ip_set_adt_opt *opt); extern int ip_set_test(ip_set_id_t id, const struct sk_buff *skb, const struct xt_action_param *par, - const struct ip_set_adt_opt *opt); + struct ip_set_adt_opt *opt); /* Utility functions */ extern void *ip_set_alloc(size_t size); extern void ip_set_free(void *members); extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr); extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr); +extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[], + struct ip_set_ext *ext); static inline int ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr) @@ -200,6 +294,16 @@ ip_set_eexist(int ret, u32 flags) return ret == -IPSET_ERR_EXIST && (flags & IPSET_FLAG_EXIST); } +/* Match elements marked with nomatch */ +static inline bool +ip_set_enomatch(int ret, u32 flags, enum ipset_adt adt, struct ip_set *set) +{ + return adt == IPSET_TEST && + (set->type->features & IPSET_TYPE_NOMATCH) && + ((flags >> 16) & IPSET_FLAG_NOMATCH) && + (ret > 0 || ret == -ENOTEMPTY); +} + /* Check the NLA_F_NET_BYTEORDER flag */ static inline bool ip_set_attr_netorder(struct nlattr *tb[], int type) @@ -284,4 +388,14 @@ bitmap_bytes(u32 a, u32 b) return 4 * ((((b - a + 8) / 8) + 3) / 4); } +#include <linux/netfilter/ipset/ip_set_timeout.h> + +#define IP_SET_INIT_KEXT(skb, opt, map) \ + { .bytes = (skb)->len, .packets = 1, \ + .timeout = ip_set_adt_opt_timeout(opt, map) } + +#define IP_SET_INIT_UEXT(map) \ + { .bytes = ULLONG_MAX, .packets = ULLONG_MAX, \ + .timeout = (map)->timeout } + #endif /*_IP_SET_H */ diff --git a/include/linux/netfilter/ipset/ip_set_ahash.h b/include/linux/netfilter/ipset/ip_set_ahash.h deleted file mode 100644 index ef9acd3c8450..000000000000 --- a/include/linux/netfilter/ipset/ip_set_ahash.h +++ /dev/null @@ -1,1223 +0,0 @@ -#ifndef _IP_SET_AHASH_H -#define _IP_SET_AHASH_H - -#include <linux/rcupdate.h> -#include <linux/jhash.h> -#include <linux/netfilter/ipset/ip_set_timeout.h> - -#define CONCAT(a, b, c) a##b##c -#define TOKEN(a, b, c) CONCAT(a, b, c) - -#define type_pf_next TOKEN(TYPE, PF, _elem) - -/* Hashing which uses arrays to resolve clashing. The hash table is resized - * (doubled) when searching becomes too long. - * Internally jhash is used with the assumption that the size of the - * stored data is a multiple of sizeof(u32). If storage supports timeout, - * the timeout field must be the last one in the data structure - that field - * is ignored when computing the hash key. - * - * Readers and resizing - * - * Resizing can be triggered by userspace command only, and those - * are serialized by the nfnl mutex. During resizing the set is - * read-locked, so the only possible concurrent operations are - * the kernel side readers. Those must be protected by proper RCU locking. - */ - -/* Number of elements to store in an initial array block */ -#define AHASH_INIT_SIZE 4 -/* Max number of elements to store in an array block */ -#define AHASH_MAX_SIZE (3*AHASH_INIT_SIZE) - -/* Max number of elements can be tuned */ -#ifdef IP_SET_HASH_WITH_MULTI -#define AHASH_MAX(h) ((h)->ahash_max) - -static inline u8 -tune_ahash_max(u8 curr, u32 multi) -{ - u32 n; - - if (multi < curr) - return curr; - - n = curr + AHASH_INIT_SIZE; - /* Currently, at listing one hash bucket must fit into a message. - * Therefore we have a hard limit here. - */ - return n > curr && n <= 64 ? n : curr; -} -#define TUNE_AHASH_MAX(h, multi) \ - ((h)->ahash_max = tune_ahash_max((h)->ahash_max, multi)) -#else -#define AHASH_MAX(h) AHASH_MAX_SIZE -#define TUNE_AHASH_MAX(h, multi) -#endif - -/* A hash bucket */ -struct hbucket { - void *value; /* the array of the values */ - u8 size; /* size of the array */ - u8 pos; /* position of the first free entry */ -}; - -/* The hash table: the table size stored here in order to make resizing easy */ -struct htable { - u8 htable_bits; /* size of hash table == 2^htable_bits */ - struct hbucket bucket[0]; /* hashtable buckets */ -}; - -#define hbucket(h, i) (&((h)->bucket[i])) - -/* Book-keeping of the prefixes added to the set */ -struct ip_set_hash_nets { - u8 cidr; /* the different cidr values in the set */ - u32 nets; /* number of elements per cidr */ -}; - -/* The generic ip_set hash structure */ -struct ip_set_hash { - struct htable *table; /* the hash table */ - u32 maxelem; /* max elements in the hash */ - u32 elements; /* current element (vs timeout) */ - u32 initval; /* random jhash init value */ - u32 timeout; /* timeout value, if enabled */ - struct timer_list gc; /* garbage collection when timeout enabled */ - struct type_pf_next next; /* temporary storage for uadd */ -#ifdef IP_SET_HASH_WITH_MULTI - u8 ahash_max; /* max elements in an array block */ -#endif -#ifdef IP_SET_HASH_WITH_NETMASK - u8 netmask; /* netmask value for subnets to store */ -#endif -#ifdef IP_SET_HASH_WITH_RBTREE - struct rb_root rbtree; -#endif -#ifdef IP_SET_HASH_WITH_NETS - struct ip_set_hash_nets nets[0]; /* book-keeping of prefixes */ -#endif -}; - -static size_t -htable_size(u8 hbits) -{ - size_t hsize; - - /* We must fit both into u32 in jhash and size_t */ - if (hbits > 31) - return 0; - hsize = jhash_size(hbits); - if ((((size_t)-1) - sizeof(struct htable))/sizeof(struct hbucket) - < hsize) - return 0; - - return hsize * sizeof(struct hbucket) + sizeof(struct htable); -} - -/* Compute htable_bits from the user input parameter hashsize */ -static u8 -htable_bits(u32 hashsize) -{ - /* Assume that hashsize == 2^htable_bits */ - u8 bits = fls(hashsize - 1); - if (jhash_size(bits) != hashsize) - /* Round up to the first 2^n value */ - bits = fls(hashsize); - - return bits; -} - -#ifdef IP_SET_HASH_WITH_NETS -#ifdef IP_SET_HASH_WITH_NETS_PACKED -/* When cidr is packed with nomatch, cidr - 1 is stored in the entry */ -#define CIDR(cidr) (cidr + 1) -#else -#define CIDR(cidr) (cidr) -#endif - -#define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128) -#ifdef IP_SET_HASH_WITH_MULTI -#define NETS_LENGTH(family) (SET_HOST_MASK(family) + 1) -#else -#define NETS_LENGTH(family) SET_HOST_MASK(family) -#endif - -/* Network cidr size book keeping when the hash stores different - * sized networks */ -static void -add_cidr(struct ip_set_hash *h, u8 cidr, u8 nets_length) -{ - int i, j; - - /* Add in increasing prefix order, so larger cidr first */ - for (i = 0, j = -1; i < nets_length && h->nets[i].nets; i++) { - if (j != -1) - continue; - else if (h->nets[i].cidr < cidr) - j = i; - else if (h->nets[i].cidr == cidr) { - h->nets[i].nets++; - return; - } - } - if (j != -1) { - for (; i > j; i--) { - h->nets[i].cidr = h->nets[i - 1].cidr; - h->nets[i].nets = h->nets[i - 1].nets; - } - } - h->nets[i].cidr = cidr; - h->nets[i].nets = 1; -} - -static void -del_cidr(struct ip_set_hash *h, u8 cidr, u8 nets_length) -{ - u8 i, j; - - for (i = 0; i < nets_length - 1 && h->nets[i].cidr != cidr; i++) - ; - h->nets[i].nets--; - - if (h->nets[i].nets != 0) - return; - - for (j = i; j < nets_length - 1 && h->nets[j].nets; j++) { - h->nets[j].cidr = h->nets[j + 1].cidr; - h->nets[j].nets = h->nets[j + 1].nets; - } -} -#else -#define NETS_LENGTH(family) 0 -#endif - -/* Destroy the hashtable part of the set */ -static void -ahash_destroy(struct htable *t) -{ - struct hbucket *n; - u32 i; - - for (i = 0; i < jhash_size(t->htable_bits); i++) { - n = hbucket(t, i); - if (n->size) - /* FIXME: use slab cache */ - kfree(n->value); - } - - ip_set_free(t); -} - -/* Calculate the actual memory size of the set data */ -static size_t -ahash_memsize(const struct ip_set_hash *h, size_t dsize, u8 nets_length) -{ - u32 i; - struct htable *t = h->table; - size_t memsize = sizeof(*h) - + sizeof(*t) -#ifdef IP_SET_HASH_WITH_NETS - + sizeof(struct ip_set_hash_nets) * nets_length -#endif - + jhash_size(t->htable_bits) * sizeof(struct hbucket); - - for (i = 0; i < jhash_size(t->htable_bits); i++) - memsize += t->bucket[i].size * dsize; - - return memsize; -} - -/* Flush a hash type of set: destroy all elements */ -static void -ip_set_hash_flush(struct ip_set *set) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - struct hbucket *n; - u32 i; - - for (i = 0; i < jhash_size(t->htable_bits); i++) { - n = hbucket(t, i); - if (n->size) { - n->size = n->pos = 0; - /* FIXME: use slab cache */ - kfree(n->value); - } - } -#ifdef IP_SET_HASH_WITH_NETS - memset(h->nets, 0, sizeof(struct ip_set_hash_nets) - * NETS_LENGTH(set->family)); -#endif - h->elements = 0; -} - -/* Destroy a hash type of set */ -static void -ip_set_hash_destroy(struct ip_set *set) -{ - struct ip_set_hash *h = set->data; - - if (with_timeout(h->timeout)) - del_timer_sync(&h->gc); - - ahash_destroy(h->table); -#ifdef IP_SET_HASH_WITH_RBTREE - rbtree_destroy(&h->rbtree); -#endif - kfree(h); - - set->data = NULL; -} - -#endif /* _IP_SET_AHASH_H */ - -#ifndef HKEY_DATALEN -#define HKEY_DATALEN sizeof(struct type_pf_elem) -#endif - -#define HKEY(data, initval, htable_bits) \ -(jhash2((u32 *)(data), HKEY_DATALEN/sizeof(u32), initval) \ - & jhash_mask(htable_bits)) - -/* Type/family dependent function prototypes */ - -#define type_pf_data_equal TOKEN(TYPE, PF, _data_equal) -#define type_pf_data_isnull TOKEN(TYPE, PF, _data_isnull) -#define type_pf_data_copy TOKEN(TYPE, PF, _data_copy) -#define type_pf_data_zero_out TOKEN(TYPE, PF, _data_zero_out) -#define type_pf_data_netmask TOKEN(TYPE, PF, _data_netmask) -#define type_pf_data_list TOKEN(TYPE, PF, _data_list) -#define type_pf_data_tlist TOKEN(TYPE, PF, _data_tlist) -#define type_pf_data_next TOKEN(TYPE, PF, _data_next) -#define type_pf_data_flags TOKEN(TYPE, PF, _data_flags) -#ifdef IP_SET_HASH_WITH_NETS -#define type_pf_data_match TOKEN(TYPE, PF, _data_match) -#else -#define type_pf_data_match(d) 1 -#endif - -#define type_pf_elem TOKEN(TYPE, PF, _elem) -#define type_pf_telem TOKEN(TYPE, PF, _telem) -#define type_pf_data_timeout TOKEN(TYPE, PF, _data_timeout) -#define type_pf_data_expired TOKEN(TYPE, PF, _data_expired) -#define type_pf_data_timeout_set TOKEN(TYPE, PF, _data_timeout_set) - -#define type_pf_elem_add TOKEN(TYPE, PF, _elem_add) -#define type_pf_add TOKEN(TYPE, PF, _add) -#define type_pf_del TOKEN(TYPE, PF, _del) -#define type_pf_test_cidrs TOKEN(TYPE, PF, _test_cidrs) -#define type_pf_test TOKEN(TYPE, PF, _test) - -#define type_pf_elem_tadd TOKEN(TYPE, PF, _elem_tadd) -#define type_pf_del_telem TOKEN(TYPE, PF, _ahash_del_telem) -#define type_pf_expire TOKEN(TYPE, PF, _expire) -#define type_pf_tadd TOKEN(TYPE, PF, _tadd) -#define type_pf_tdel TOKEN(TYPE, PF, _tdel) -#define type_pf_ttest_cidrs TOKEN(TYPE, PF, _ahash_ttest_cidrs) -#define type_pf_ttest TOKEN(TYPE, PF, _ahash_ttest) - -#define type_pf_resize TOKEN(TYPE, PF, _resize) -#define type_pf_tresize TOKEN(TYPE, PF, _tresize) -#define type_pf_flush ip_set_hash_flush -#define type_pf_destroy ip_set_hash_destroy -#define type_pf_head TOKEN(TYPE, PF, _head) -#define type_pf_list TOKEN(TYPE, PF, _list) -#define type_pf_tlist TOKEN(TYPE, PF, _tlist) -#define type_pf_same_set TOKEN(TYPE, PF, _same_set) -#define type_pf_kadt TOKEN(TYPE, PF, _kadt) -#define type_pf_uadt TOKEN(TYPE, PF, _uadt) -#define type_pf_gc TOKEN(TYPE, PF, _gc) -#define type_pf_gc_init TOKEN(TYPE, PF, _gc_init) -#define type_pf_variant TOKEN(TYPE, PF, _variant) -#define type_pf_tvariant TOKEN(TYPE, PF, _tvariant) - -/* Flavour without timeout */ - -/* Get the ith element from the array block n */ -#define ahash_data(n, i) \ - ((struct type_pf_elem *)((n)->value) + (i)) - -/* Add an element to the hash table when resizing the set: - * we spare the maintenance of the internal counters. */ -static int -type_pf_elem_add(struct hbucket *n, const struct type_pf_elem *value, - u8 ahash_max, u32 cadt_flags) -{ - struct type_pf_elem *data; - - if (n->pos >= n->size) { - void *tmp; - - if (n->size >= ahash_max) - /* Trigger rehashing */ - return -EAGAIN; - - tmp = kzalloc((n->size + AHASH_INIT_SIZE) - * sizeof(struct type_pf_elem), - GFP_ATOMIC); - if (!tmp) - return -ENOMEM; - if (n->size) { - memcpy(tmp, n->value, - sizeof(struct type_pf_elem) * n->size); - kfree(n->value); - } - n->value = tmp; - n->size += AHASH_INIT_SIZE; - } - data = ahash_data(n, n->pos++); - type_pf_data_copy(data, value); -#ifdef IP_SET_HASH_WITH_NETS - /* Resizing won't overwrite stored flags */ - if (cadt_flags) - type_pf_data_flags(data, cadt_flags); -#endif - return 0; -} - -/* Resize a hash: create a new hash table with doubling the hashsize - * and inserting the elements to it. Repeat until we succeed or - * fail due to memory pressures. */ -static int -type_pf_resize(struct ip_set *set, bool retried) -{ - struct ip_set_hash *h = set->data; - struct htable *t, *orig = h->table; - u8 htable_bits = orig->htable_bits; - const struct type_pf_elem *data; - struct hbucket *n, *m; - u32 i, j; - int ret; - -retry: - ret = 0; - htable_bits++; - pr_debug("attempt to resize set %s from %u to %u, t %p\n", - set->name, orig->htable_bits, htable_bits, orig); - if (!htable_bits) { - /* In case we have plenty of memory :-) */ - pr_warning("Cannot increase the hashsize of set %s further\n", - set->name); - return -IPSET_ERR_HASH_FULL; - } - t = ip_set_alloc(sizeof(*t) - + jhash_size(htable_bits) * sizeof(struct hbucket)); - if (!t) - return -ENOMEM; - t->htable_bits = htable_bits; - - read_lock_bh(&set->lock); - for (i = 0; i < jhash_size(orig->htable_bits); i++) { - n = hbucket(orig, i); - for (j = 0; j < n->pos; j++) { - data = ahash_data(n, j); - m = hbucket(t, HKEY(data, h->initval, htable_bits)); - ret = type_pf_elem_add(m, data, AHASH_MAX(h), 0); - if (ret < 0) { - read_unlock_bh(&set->lock); - ahash_destroy(t); - if (ret == -EAGAIN) - goto retry; - return ret; - } - } - } - - rcu_assign_pointer(h->table, t); - read_unlock_bh(&set->lock); - - /* Give time to other readers of the set */ - synchronize_rcu_bh(); - - pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name, - orig->htable_bits, orig, t->htable_bits, t); - ahash_destroy(orig); - - return 0; -} - -static inline void -type_pf_data_next(struct ip_set_hash *h, const struct type_pf_elem *d); - -/* Add an element to a hash and update the internal counters when succeeded, - * otherwise report the proper error code. */ -static int -type_pf_add(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t; - const struct type_pf_elem *d = value; - struct hbucket *n; - int i, ret = 0; - u32 key, multi = 0; - u32 cadt_flags = flags >> 16; - - if (h->elements >= h->maxelem) { - if (net_ratelimit()) - pr_warning("Set %s is full, maxelem %u reached\n", - set->name, h->maxelem); - return -IPSET_ERR_HASH_FULL; - } - - rcu_read_lock_bh(); - t = rcu_dereference_bh(h->table); - key = HKEY(value, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) - if (type_pf_data_equal(ahash_data(n, i), d, &multi)) { -#ifdef IP_SET_HASH_WITH_NETS - if (flags & IPSET_FLAG_EXIST) - /* Support overwriting just the flags */ - type_pf_data_flags(ahash_data(n, i), - cadt_flags); -#endif - ret = -IPSET_ERR_EXIST; - goto out; - } - TUNE_AHASH_MAX(h, multi); - ret = type_pf_elem_add(n, value, AHASH_MAX(h), cadt_flags); - if (ret != 0) { - if (ret == -EAGAIN) - type_pf_data_next(h, d); - goto out; - } - -#ifdef IP_SET_HASH_WITH_NETS - add_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family)); -#endif - h->elements++; -out: - rcu_read_unlock_bh(); - return ret; -} - -/* Delete an element from the hash: swap it with the last element - * and free up space if possible. - */ -static int -type_pf_del(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - const struct type_pf_elem *d = value; - struct hbucket *n; - int i; - struct type_pf_elem *data; - u32 key, multi = 0; - - key = HKEY(value, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_data(n, i); - if (!type_pf_data_equal(data, d, &multi)) - continue; - if (i != n->pos - 1) - /* Not last one */ - type_pf_data_copy(data, ahash_data(n, n->pos - 1)); - - n->pos--; - h->elements--; -#ifdef IP_SET_HASH_WITH_NETS - del_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family)); -#endif - if (n->pos + AHASH_INIT_SIZE < n->size) { - void *tmp = kzalloc((n->size - AHASH_INIT_SIZE) - * sizeof(struct type_pf_elem), - GFP_ATOMIC); - if (!tmp) - return 0; - n->size -= AHASH_INIT_SIZE; - memcpy(tmp, n->value, - n->size * sizeof(struct type_pf_elem)); - kfree(n->value); - n->value = tmp; - } - return 0; - } - - return -IPSET_ERR_EXIST; -} - -#ifdef IP_SET_HASH_WITH_NETS - -/* Special test function which takes into account the different network - * sizes added to the set */ -static int -type_pf_test_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - struct hbucket *n; - const struct type_pf_elem *data; - int i, j = 0; - u32 key, multi = 0; - u8 nets_length = NETS_LENGTH(set->family); - - pr_debug("test by nets\n"); - for (; j < nets_length && h->nets[j].nets && !multi; j++) { - type_pf_data_netmask(d, h->nets[j].cidr); - key = HKEY(d, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_data(n, i); - if (type_pf_data_equal(data, d, &multi)) - return type_pf_data_match(data); - } - } - return 0; -} -#endif - -/* Test whether the element is added to the set */ -static int -type_pf_test(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - struct type_pf_elem *d = value; - struct hbucket *n; - const struct type_pf_elem *data; - int i; - u32 key, multi = 0; - -#ifdef IP_SET_HASH_WITH_NETS - /* If we test an IP address and not a network address, - * try all possible network sizes */ - if (CIDR(d->cidr) == SET_HOST_MASK(set->family)) - return type_pf_test_cidrs(set, d, timeout); -#endif - - key = HKEY(d, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_data(n, i); - if (type_pf_data_equal(data, d, &multi)) - return type_pf_data_match(data); - } - return 0; -} - -/* Reply a HEADER request: fill out the header part of the set */ -static int -type_pf_head(struct ip_set *set, struct sk_buff *skb) -{ - const struct ip_set_hash *h = set->data; - struct nlattr *nested; - size_t memsize; - - read_lock_bh(&set->lock); - memsize = ahash_memsize(h, with_timeout(h->timeout) - ? sizeof(struct type_pf_telem) - : sizeof(struct type_pf_elem), - NETS_LENGTH(set->family)); - read_unlock_bh(&set->lock); - - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) - goto nla_put_failure; - if (nla_put_net32(skb, IPSET_ATTR_HASHSIZE, - htonl(jhash_size(h->table->htable_bits))) || - nla_put_net32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem))) - goto nla_put_failure; -#ifdef IP_SET_HASH_WITH_NETMASK - if (h->netmask != HOST_MASK && - nla_put_u8(skb, IPSET_ATTR_NETMASK, h->netmask)) - goto nla_put_failure; -#endif - if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || - nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) || - (with_timeout(h->timeout) && - nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout)))) - goto nla_put_failure; - ipset_nest_end(skb, nested); - - return 0; -nla_put_failure: - return -EMSGSIZE; -} - -/* Reply a LIST/SAVE request: dump the elements of the specified set */ -static int -type_pf_list(const struct ip_set *set, - struct sk_buff *skb, struct netlink_callback *cb) -{ - const struct ip_set_hash *h = set->data; - const struct htable *t = h->table; - struct nlattr *atd, *nested; - const struct hbucket *n; - const struct type_pf_elem *data; - u32 first = cb->args[2]; - /* We assume that one hash bucket fills into one page */ - void *incomplete; - int i; - - atd = ipset_nest_start(skb, IPSET_ATTR_ADT); - if (!atd) - return -EMSGSIZE; - pr_debug("list hash set %s\n", set->name); - for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) { - incomplete = skb_tail_pointer(skb); - n = hbucket(t, cb->args[2]); - pr_debug("cb->args[2]: %lu, t %p n %p\n", cb->args[2], t, n); - for (i = 0; i < n->pos; i++) { - data = ahash_data(n, i); - pr_debug("list hash %lu hbucket %p i %u, data %p\n", - cb->args[2], n, i, data); - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) { - if (cb->args[2] == first) { - nla_nest_cancel(skb, atd); - return -EMSGSIZE; - } else - goto nla_put_failure; - } - if (type_pf_data_list(skb, data)) - goto nla_put_failure; - ipset_nest_end(skb, nested); - } - } - ipset_nest_end(skb, atd); - /* Set listing finished */ - cb->args[2] = 0; - - return 0; - -nla_put_failure: - nlmsg_trim(skb, incomplete); - ipset_nest_end(skb, atd); - if (unlikely(first == cb->args[2])) { - pr_warning("Can't list set %s: one bucket does not fit into " - "a message. Please report it!\n", set->name); - cb->args[2] = 0; - return -EMSGSIZE; - } - return 0; -} - -static int -type_pf_kadt(struct ip_set *set, const struct sk_buff *skb, - const struct xt_action_param *par, - enum ipset_adt adt, const struct ip_set_adt_opt *opt); -static int -type_pf_uadt(struct ip_set *set, struct nlattr *tb[], - enum ipset_adt adt, u32 *lineno, u32 flags, bool retried); - -static const struct ip_set_type_variant type_pf_variant = { - .kadt = type_pf_kadt, - .uadt = type_pf_uadt, - .adt = { - [IPSET_ADD] = type_pf_add, - [IPSET_DEL] = type_pf_del, - [IPSET_TEST] = type_pf_test, - }, - .destroy = type_pf_destroy, - .flush = type_pf_flush, - .head = type_pf_head, - .list = type_pf_list, - .resize = type_pf_resize, - .same_set = type_pf_same_set, -}; - -/* Flavour with timeout support */ - -#define ahash_tdata(n, i) \ - (struct type_pf_elem *)((struct type_pf_telem *)((n)->value) + (i)) - -static inline u32 -type_pf_data_timeout(const struct type_pf_elem *data) -{ - const struct type_pf_telem *tdata = - (const struct type_pf_telem *) data; - - return tdata->timeout; -} - -static inline bool -type_pf_data_expired(const struct type_pf_elem *data) -{ - const struct type_pf_telem *tdata = - (const struct type_pf_telem *) data; - - return ip_set_timeout_expired(tdata->timeout); -} - -static inline void -type_pf_data_timeout_set(struct type_pf_elem *data, u32 timeout) -{ - struct type_pf_telem *tdata = (struct type_pf_telem *) data; - - tdata->timeout = ip_set_timeout_set(timeout); -} - -static int -type_pf_elem_tadd(struct hbucket *n, const struct type_pf_elem *value, - u8 ahash_max, u32 cadt_flags, u32 timeout) -{ - struct type_pf_elem *data; - - if (n->pos >= n->size) { - void *tmp; - - if (n->size >= ahash_max) - /* Trigger rehashing */ - return -EAGAIN; - - tmp = kzalloc((n->size + AHASH_INIT_SIZE) - * sizeof(struct type_pf_telem), - GFP_ATOMIC); - if (!tmp) - return -ENOMEM; - if (n->size) { - memcpy(tmp, n->value, - sizeof(struct type_pf_telem) * n->size); - kfree(n->value); - } - n->value = tmp; - n->size += AHASH_INIT_SIZE; - } - data = ahash_tdata(n, n->pos++); - type_pf_data_copy(data, value); - type_pf_data_timeout_set(data, timeout); -#ifdef IP_SET_HASH_WITH_NETS - /* Resizing won't overwrite stored flags */ - if (cadt_flags) - type_pf_data_flags(data, cadt_flags); -#endif - return 0; -} - -/* Delete expired elements from the hashtable */ -static void -type_pf_expire(struct ip_set_hash *h, u8 nets_length) -{ - struct htable *t = h->table; - struct hbucket *n; - struct type_pf_elem *data; - u32 i; - int j; - - for (i = 0; i < jhash_size(t->htable_bits); i++) { - n = hbucket(t, i); - for (j = 0; j < n->pos; j++) { - data = ahash_tdata(n, j); - if (type_pf_data_expired(data)) { - pr_debug("expired %u/%u\n", i, j); -#ifdef IP_SET_HASH_WITH_NETS - del_cidr(h, CIDR(data->cidr), nets_length); -#endif - if (j != n->pos - 1) - /* Not last one */ - type_pf_data_copy(data, - ahash_tdata(n, n->pos - 1)); - n->pos--; - h->elements--; - } - } - if (n->pos + AHASH_INIT_SIZE < n->size) { - void *tmp = kzalloc((n->size - AHASH_INIT_SIZE) - * sizeof(struct type_pf_telem), - GFP_ATOMIC); - if (!tmp) - /* Still try to delete expired elements */ - continue; - n->size -= AHASH_INIT_SIZE; - memcpy(tmp, n->value, - n->size * sizeof(struct type_pf_telem)); - kfree(n->value); - n->value = tmp; - } - } -} - -static int -type_pf_tresize(struct ip_set *set, bool retried) -{ - struct ip_set_hash *h = set->data; - struct htable *t, *orig = h->table; - u8 htable_bits = orig->htable_bits; - const struct type_pf_elem *data; - struct hbucket *n, *m; - u32 i, j; - int ret; - - /* Try to cleanup once */ - if (!retried) { - i = h->elements; - write_lock_bh(&set->lock); - type_pf_expire(set->data, NETS_LENGTH(set->family)); - write_unlock_bh(&set->lock); - if (h->elements < i) - return 0; - } - -retry: - ret = 0; - htable_bits++; - if (!htable_bits) { - /* In case we have plenty of memory :-) */ - pr_warning("Cannot increase the hashsize of set %s further\n", - set->name); - return -IPSET_ERR_HASH_FULL; - } - t = ip_set_alloc(sizeof(*t) - + jhash_size(htable_bits) * sizeof(struct hbucket)); - if (!t) - return -ENOMEM; - t->htable_bits = htable_bits; - - read_lock_bh(&set->lock); - for (i = 0; i < jhash_size(orig->htable_bits); i++) { - n = hbucket(orig, i); - for (j = 0; j < n->pos; j++) { - data = ahash_tdata(n, j); - m = hbucket(t, HKEY(data, h->initval, htable_bits)); - ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), 0, - type_pf_data_timeout(data)); - if (ret < 0) { - read_unlock_bh(&set->lock); - ahash_destroy(t); - if (ret == -EAGAIN) - goto retry; - return ret; - } - } - } - - rcu_assign_pointer(h->table, t); - read_unlock_bh(&set->lock); - - /* Give time to other readers of the set */ - synchronize_rcu_bh(); - - ahash_destroy(orig); - - return 0; -} - -static int -type_pf_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - const struct type_pf_elem *d = value; - struct hbucket *n; - struct type_pf_elem *data; - int ret = 0, i, j = AHASH_MAX(h) + 1; - bool flag_exist = flags & IPSET_FLAG_EXIST; - u32 key, multi = 0; - u32 cadt_flags = flags >> 16; - - if (h->elements >= h->maxelem) - /* FIXME: when set is full, we slow down here */ - type_pf_expire(h, NETS_LENGTH(set->family)); - if (h->elements >= h->maxelem) { - if (net_ratelimit()) - pr_warning("Set %s is full, maxelem %u reached\n", - set->name, h->maxelem); - return -IPSET_ERR_HASH_FULL; - } - - rcu_read_lock_bh(); - t = rcu_dereference_bh(h->table); - key = HKEY(d, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_tdata(n, i); - if (type_pf_data_equal(data, d, &multi)) { - if (type_pf_data_expired(data) || flag_exist) - /* Just timeout value may be updated */ - j = i; - else { - ret = -IPSET_ERR_EXIST; - goto out; - } - } else if (j == AHASH_MAX(h) + 1 && - type_pf_data_expired(data)) - j = i; - } - if (j != AHASH_MAX(h) + 1) { - data = ahash_tdata(n, j); -#ifdef IP_SET_HASH_WITH_NETS - del_cidr(h, CIDR(data->cidr), NETS_LENGTH(set->family)); - add_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family)); -#endif - type_pf_data_copy(data, d); - type_pf_data_timeout_set(data, timeout); -#ifdef IP_SET_HASH_WITH_NETS - type_pf_data_flags(data, cadt_flags); -#endif - goto out; - } - TUNE_AHASH_MAX(h, multi); - ret = type_pf_elem_tadd(n, d, AHASH_MAX(h), cadt_flags, timeout); - if (ret != 0) { - if (ret == -EAGAIN) - type_pf_data_next(h, d); - goto out; - } - -#ifdef IP_SET_HASH_WITH_NETS - add_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family)); -#endif - h->elements++; -out: - rcu_read_unlock_bh(); - return ret; -} - -static int -type_pf_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - const struct type_pf_elem *d = value; - struct hbucket *n; - int i; - struct type_pf_elem *data; - u32 key, multi = 0; - - key = HKEY(value, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_tdata(n, i); - if (!type_pf_data_equal(data, d, &multi)) - continue; - if (type_pf_data_expired(data)) - return -IPSET_ERR_EXIST; - if (i != n->pos - 1) - /* Not last one */ - type_pf_data_copy(data, ahash_tdata(n, n->pos - 1)); - - n->pos--; - h->elements--; -#ifdef IP_SET_HASH_WITH_NETS - del_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family)); -#endif - if (n->pos + AHASH_INIT_SIZE < n->size) { - void *tmp = kzalloc((n->size - AHASH_INIT_SIZE) - * sizeof(struct type_pf_telem), - GFP_ATOMIC); - if (!tmp) - return 0; - n->size -= AHASH_INIT_SIZE; - memcpy(tmp, n->value, - n->size * sizeof(struct type_pf_telem)); - kfree(n->value); - n->value = tmp; - } - return 0; - } - - return -IPSET_ERR_EXIST; -} - -#ifdef IP_SET_HASH_WITH_NETS -static int -type_pf_ttest_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - struct type_pf_elem *data; - struct hbucket *n; - int i, j = 0; - u32 key, multi = 0; - u8 nets_length = NETS_LENGTH(set->family); - - for (; j < nets_length && h->nets[j].nets && !multi; j++) { - type_pf_data_netmask(d, h->nets[j].cidr); - key = HKEY(d, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_tdata(n, i); -#ifdef IP_SET_HASH_WITH_MULTI - if (type_pf_data_equal(data, d, &multi)) { - if (!type_pf_data_expired(data)) - return type_pf_data_match(data); - multi = 0; - } -#else - if (type_pf_data_equal(data, d, &multi) && - !type_pf_data_expired(data)) - return type_pf_data_match(data); -#endif - } - } - return 0; -} -#endif - -static int -type_pf_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags) -{ - struct ip_set_hash *h = set->data; - struct htable *t = h->table; - struct type_pf_elem *data, *d = value; - struct hbucket *n; - int i; - u32 key, multi = 0; - -#ifdef IP_SET_HASH_WITH_NETS - if (CIDR(d->cidr) == SET_HOST_MASK(set->family)) - return type_pf_ttest_cidrs(set, d, timeout); -#endif - key = HKEY(d, h->initval, t->htable_bits); - n = hbucket(t, key); - for (i = 0; i < n->pos; i++) { - data = ahash_tdata(n, i); - if (type_pf_data_equal(data, d, &multi) && - !type_pf_data_expired(data)) - return type_pf_data_match(data); - } - return 0; -} - -static int -type_pf_tlist(const struct ip_set *set, - struct sk_buff *skb, struct netlink_callback *cb) -{ - const struct ip_set_hash *h = set->data; - const struct htable *t = h->table; - struct nlattr *atd, *nested; - const struct hbucket *n; - const struct type_pf_elem *data; - u32 first = cb->args[2]; - /* We assume that one hash bucket fills into one page */ - void *incomplete; - int i; - - atd = ipset_nest_start(skb, IPSET_ATTR_ADT); - if (!atd) - return -EMSGSIZE; - for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) { - incomplete = skb_tail_pointer(skb); - n = hbucket(t, cb->args[2]); - for (i = 0; i < n->pos; i++) { - data = ahash_tdata(n, i); - pr_debug("list %p %u\n", n, i); - if (type_pf_data_expired(data)) - continue; - pr_debug("do list %p %u\n", n, i); - nested = ipset_nest_start(skb, IPSET_ATTR_DATA); - if (!nested) { - if (cb->args[2] == first) { - nla_nest_cancel(skb, atd); - return -EMSGSIZE; - } else - goto nla_put_failure; - } - if (type_pf_data_tlist(skb, data)) - goto nla_put_failure; - ipset_nest_end(skb, nested); - } - } - ipset_nest_end(skb, atd); - /* Set listing finished */ - cb->args[2] = 0; - - return 0; - -nla_put_failure: - nlmsg_trim(skb, incomplete); - ipset_nest_end(skb, atd); - if (unlikely(first == cb->args[2])) { - pr_warning("Can't list set %s: one bucket does not fit into " - "a message. Please report it!\n", set->name); - cb->args[2] = 0; - return -EMSGSIZE; - } - return 0; -} - -static const struct ip_set_type_variant type_pf_tvariant = { - .kadt = type_pf_kadt, - .uadt = type_pf_uadt, - .adt = { - [IPSET_ADD] = type_pf_tadd, - [IPSET_DEL] = type_pf_tdel, - [IPSET_TEST] = type_pf_ttest, - }, - .destroy = type_pf_destroy, - .flush = type_pf_flush, - .head = type_pf_head, - .list = type_pf_tlist, - .resize = type_pf_tresize, - .same_set = type_pf_same_set, -}; - -static void -type_pf_gc(unsigned long ul_set) -{ - struct ip_set *set = (struct ip_set *) ul_set; - struct ip_set_hash *h = set->data; - - pr_debug("called\n"); - write_lock_bh(&set->lock); - type_pf_expire(h, NETS_LENGTH(set->family)); - write_unlock_bh(&set->lock); - - h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ; - add_timer(&h->gc); -} - -static void -type_pf_gc_init(struct ip_set *set) -{ - struct ip_set_hash *h = set->data; - - init_timer(&h->gc); - h->gc.data = (unsigned long) set; - h->gc.function = type_pf_gc; - h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ; - add_timer(&h->gc); - pr_debug("gc initialized, run in every %u\n", - IPSET_GC_PERIOD(h->timeout)); -} - -#undef HKEY_DATALEN -#undef HKEY -#undef type_pf_data_equal -#undef type_pf_data_isnull -#undef type_pf_data_copy -#undef type_pf_data_zero_out -#undef type_pf_data_netmask -#undef type_pf_data_list -#undef type_pf_data_tlist -#undef type_pf_data_next -#undef type_pf_data_flags -#undef type_pf_data_match - -#undef type_pf_elem -#undef type_pf_telem -#undef type_pf_data_timeout -#undef type_pf_data_expired -#undef type_pf_data_timeout_set - -#undef type_pf_elem_add -#undef type_pf_add -#undef type_pf_del -#undef type_pf_test_cidrs -#undef type_pf_test - -#undef type_pf_elem_tadd -#undef type_pf_del_telem -#undef type_pf_expire -#undef type_pf_tadd -#undef type_pf_tdel -#undef type_pf_ttest_cidrs -#undef type_pf_ttest - -#undef type_pf_resize -#undef type_pf_tresize -#undef type_pf_flush -#undef type_pf_destroy -#undef type_pf_head -#undef type_pf_list -#undef type_pf_tlist -#undef type_pf_same_set -#undef type_pf_kadt -#undef type_pf_uadt -#undef type_pf_gc -#undef type_pf_gc_init -#undef type_pf_variant -#undef type_pf_tvariant diff --git a/include/linux/netfilter/ipset/ip_set_bitmap.h b/include/linux/netfilter/ipset/ip_set_bitmap.h index 1a30646d5be8..5e4662a71e01 100644 --- a/include/linux/netfilter/ipset/ip_set_bitmap.h +++ b/include/linux/netfilter/ipset/ip_set_bitmap.h @@ -5,6 +5,12 @@ #define IPSET_BITMAP_MAX_RANGE 0x0000FFFF +enum { + IPSET_ADD_FAILED = 1, + IPSET_ADD_STORE_PLAIN_TIMEOUT, + IPSET_ADD_START_STORED_TIMEOUT, +}; + /* Common functions */ static inline u32 diff --git a/include/linux/netfilter/ipset/ip_set_timeout.h b/include/linux/netfilter/ipset/ip_set_timeout.h index 41d9cfa08167..3aac04167ca7 100644 --- a/include/linux/netfilter/ipset/ip_set_timeout.h +++ b/include/linux/netfilter/ipset/ip_set_timeout.h @@ -1,7 +1,7 @@ #ifndef _IP_SET_TIMEOUT_H #define _IP_SET_TIMEOUT_H -/* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> +/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> * * 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 @@ -17,13 +17,14 @@ #define IPSET_GC_PERIOD(timeout) \ ((timeout/3) ? min_t(u32, (timeout)/3, IPSET_GC_TIME) : 1) -/* Set is defined without timeout support: timeout value may be 0 */ -#define IPSET_NO_TIMEOUT UINT_MAX +/* Entry is set with no timeout value */ +#define IPSET_ELEM_PERMANENT 0 -#define with_timeout(timeout) ((timeout) != IPSET_NO_TIMEOUT) +/* Set is defined with timeout support: timeout value may be 0 */ +#define IPSET_NO_TIMEOUT UINT_MAX -#define opt_timeout(opt, map) \ - (with_timeout((opt)->timeout) ? (opt)->timeout : (map)->timeout) +#define ip_set_adt_opt_timeout(opt, map) \ +((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (map)->timeout) static inline unsigned int ip_set_timeout_uget(struct nlattr *tb) @@ -38,61 +39,6 @@ ip_set_timeout_uget(struct nlattr *tb) return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout; } -#ifdef IP_SET_BITMAP_TIMEOUT - -/* Bitmap specific timeout constants and macros for the entries */ - -/* Bitmap entry is unset */ -#define IPSET_ELEM_UNSET 0 -/* Bitmap entry is set with no timeout value */ -#define IPSET_ELEM_PERMANENT (UINT_MAX/2) - -static inline bool -ip_set_timeout_test(unsigned long timeout) -{ - return timeout != IPSET_ELEM_UNSET && - (timeout == IPSET_ELEM_PERMANENT || - time_is_after_jiffies(timeout)); -} - -static inline bool -ip_set_timeout_expired(unsigned long timeout) -{ - return timeout != IPSET_ELEM_UNSET && - timeout != IPSET_ELEM_PERMANENT && - time_is_before_jiffies(timeout); -} - -static inline unsigned long -ip_set_timeout_set(u32 timeout) -{ - unsigned long t; - - if (!timeout) - return IPSET_ELEM_PERMANENT; - - t = msecs_to_jiffies(timeout * 1000) + jiffies; - if (t == IPSET_ELEM_UNSET || t == IPSET_ELEM_PERMANENT) - /* Bingo! */ - t++; - - return t; -} - -static inline u32 -ip_set_timeout_get(unsigned long timeout) -{ - return timeout == IPSET_ELEM_PERMANENT ? 0 : - jiffies_to_msecs(timeout - jiffies)/1000; -} - -#else - -/* Hash specific timeout constants and macros for the entries */ - -/* Hash entry is set with no timeout value */ -#define IPSET_ELEM_PERMANENT 0 - static inline bool ip_set_timeout_test(unsigned long timeout) { @@ -101,36 +47,32 @@ ip_set_timeout_test(unsigned long timeout) } static inline bool -ip_set_timeout_expired(unsigned long timeout) +ip_set_timeout_expired(unsigned long *timeout) { - return timeout != IPSET_ELEM_PERMANENT && - time_is_before_jiffies(timeout); + return *timeout != IPSET_ELEM_PERMANENT && + time_is_before_jiffies(*timeout); } -static inline unsigned long -ip_set_timeout_set(u32 timeout) +static inline void +ip_set_timeout_set(unsigned long *timeout, u32 t) { - unsigned long t; - - if (!timeout) - return IPSET_ELEM_PERMANENT; + if (!t) { + *timeout = IPSET_ELEM_PERMANENT; + return; + } - t = msecs_to_jiffies(timeout * 1000) + jiffies; - if (t == IPSET_ELEM_PERMANENT) + *timeout = msecs_to_jiffies(t * 1000) + jiffies; + if (*timeout == IPSET_ELEM_PERMANENT) /* Bingo! :-) */ - t++; - - return t; + (*timeout)--; } static inline u32 -ip_set_timeout_get(unsigned long timeout) +ip_set_timeout_get(unsigned long *timeout) { - return timeout == IPSET_ELEM_PERMANENT ? 0 : - jiffies_to_msecs(timeout - jiffies)/1000; + return *timeout == IPSET_ELEM_PERMANENT ? 0 : + jiffies_to_msecs(*timeout - jiffies)/1000; } -#endif /* ! IP_SET_BITMAP_TIMEOUT */ #endif /* __KERNEL__ */ - #endif /* _IP_SET_TIMEOUT_H */ diff --git a/include/linux/netfilter/ipset/pfxlen.h b/include/linux/netfilter/ipset/pfxlen.h index 199fd11fedc0..1afbb94b4b65 100644 --- a/include/linux/netfilter/ipset/pfxlen.h +++ b/include/linux/netfilter/ipset/pfxlen.h @@ -41,4 +41,13 @@ do { \ to = from | ~ip_set_hostmask(cidr); \ } while (0) +static inline void +ip6_netmask(union nf_inet_addr *ip, u8 prefix) +{ + ip->ip6[0] &= ip_set_netmask6(prefix)[0]; + ip->ip6[1] &= ip_set_netmask6(prefix)[1]; + ip->ip6[2] &= ip_set_netmask6(prefix)[2]; + ip->ip6[3] &= ip_set_netmask6(prefix)[3]; +} + #endif /*_PFXLEN_H */ diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index ecbb8e495912..cadb7402d7a7 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -29,10 +29,13 @@ extern int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n); extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n); extern int nfnetlink_has_listeners(struct net *net, unsigned int group); -extern int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned int group, - int echo, gfp_t flags); -extern int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error); -extern int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u_int32_t pid, int flags); +extern struct sk_buff *nfnetlink_alloc_skb(struct net *net, unsigned int size, + u32 dst_portid, gfp_t gfp_mask); +extern int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 portid, + unsigned int group, int echo, gfp_t flags); +extern int nfnetlink_set_err(struct net *net, u32 portid, u32 group, int error); +extern int nfnetlink_unicast(struct sk_buff *skb, struct net *net, + u32 portid, int flags); extern void nfnl_lock(__u8 subsys_id); extern void nfnl_unlock(__u8 subsys_id); diff --git a/include/linux/netfilter/xt_HMARK.h b/include/linux/netfilter/xt_HMARK.h deleted file mode 100644 index 826fc5807577..000000000000 --- a/include/linux/netfilter/xt_HMARK.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef XT_HMARK_H_ -#define XT_HMARK_H_ - -#include <linux/types.h> - -enum { - XT_HMARK_SADDR_MASK, - XT_HMARK_DADDR_MASK, - XT_HMARK_SPI, - XT_HMARK_SPI_MASK, - XT_HMARK_SPORT, - XT_HMARK_DPORT, - XT_HMARK_SPORT_MASK, - XT_HMARK_DPORT_MASK, - XT_HMARK_PROTO_MASK, - XT_HMARK_RND, - XT_HMARK_MODULUS, - XT_HMARK_OFFSET, - XT_HMARK_CT, - XT_HMARK_METHOD_L3, - XT_HMARK_METHOD_L3_4, -}; -#define XT_HMARK_FLAG(flag) (1 << flag) - -union hmark_ports { - struct { - __u16 src; - __u16 dst; - } p16; - struct { - __be16 src; - __be16 dst; - } b16; - __u32 v32; - __be32 b32; -}; - -struct xt_hmark_info { - union nf_inet_addr src_mask; - union nf_inet_addr dst_mask; - union hmark_ports port_mask; - union hmark_ports port_set; - __u32 flags; - __u16 proto_mask; - __u32 hashrnd; - __u32 hmodulus; - __u32 hoffset; /* Mark offset to start from */ -}; - -#endif /* XT_HMARK_H_ */ diff --git a/include/linux/netfilter/xt_rpfilter.h b/include/linux/netfilter/xt_rpfilter.h deleted file mode 100644 index 8358d4f71952..000000000000 --- a/include/linux/netfilter/xt_rpfilter.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _XT_RPATH_H -#define _XT_RPATH_H - -#include <linux/types.h> - -enum { - XT_RPFILTER_LOOSE = 1 << 0, - XT_RPFILTER_VALID_MARK = 1 << 1, - XT_RPFILTER_ACCEPT_LOCAL = 1 << 2, - XT_RPFILTER_INVERT = 1 << 3, -#ifdef __KERNEL__ - XT_RPFILTER_OPTION_MASK = XT_RPFILTER_LOOSE | - XT_RPFILTER_VALID_MARK | - XT_RPFILTER_ACCEPT_LOCAL | - XT_RPFILTER_INVERT, -#endif -}; - -struct xt_rpfilter_info { - __u8 flags; -}; - -#endif diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h index 98ffb54988b6..2d4df6ce043e 100644 --- a/include/linux/netfilter_ipv6.h +++ b/include/linux/netfilter_ipv6.h @@ -17,6 +17,22 @@ extern __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook, extern int ipv6_netfilter_init(void); extern void ipv6_netfilter_fini(void); + +/* + * Hook functions for ipv6 to allow xt_* modules to be built-in even + * if IPv6 is a module. + */ +struct nf_ipv6_ops { + int (*chk_addr)(struct net *net, const struct in6_addr *addr, + const struct net_device *dev, int strict); +}; + +extern const struct nf_ipv6_ops __rcu *nf_ipv6_ops; +static inline const struct nf_ipv6_ops *nf_get_ipv6_ops(void) +{ + return rcu_dereference(nf_ipv6_ops); +} + #else /* CONFIG_NETFILTER */ static inline int ipv6_netfilter_init(void) { return 0; } static inline void ipv6_netfilter_fini(void) { return; } diff --git a/include/linux/netlink.h b/include/linux/netlink.h index e0f746b7b95c..7a6c396a263b 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -15,11 +15,18 @@ static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb) return (struct nlmsghdr *)skb->data; } +enum netlink_skb_flags { + NETLINK_SKB_MMAPED = 0x1, /* Packet data is mmaped */ + NETLINK_SKB_TX = 0x2, /* Packet was sent by userspace */ + NETLINK_SKB_DELIVERED = 0x4, /* Packet was delivered */ +}; + struct netlink_skb_parms { struct scm_creds creds; /* Skb credentials */ __u32 portid; __u32 dst_group; - struct sock *ssk; + __u32 flags; + struct sock *sk; }; #define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) @@ -39,6 +46,7 @@ struct netlink_kernel_cfg { void (*input)(struct sk_buff *skb); struct mutex *cb_mutex; void (*bind)(int group); + bool (*compare)(struct net *net, struct sock *sk); }; extern struct sock *__netlink_kernel_create(struct net *net, int unit, @@ -57,6 +65,8 @@ extern void __netlink_clear_multicast_users(struct sock *sk, unsigned int group) extern void netlink_clear_multicast_users(struct sock *sk, unsigned int group); extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err); extern int netlink_has_listeners(struct sock *sk, unsigned int group); +extern struct sk_buff *netlink_alloc_skb(struct sock *ssk, unsigned int size, + u32 dst_portid, gfp_t gfp_mask); extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 portid, int nonblock); extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 portid, __u32 group, gfp_t allocation); @@ -75,6 +85,22 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, void netlink_detachskb(struct sock *sk, struct sk_buff *skb); int netlink_sendskb(struct sock *sk, struct sk_buff *skb); +static inline struct sk_buff * +netlink_skb_clone(struct sk_buff *skb, gfp_t gfp_mask) +{ + struct sk_buff *nskb; + + nskb = skb_clone(skb, gfp_mask); + if (!nskb) + return NULL; + + /* This is a large skb, set destructor callback to release head */ + if (is_vmalloc_addr(skb->head)) + nskb->destructor = skb->destructor; + + return nskb; +} + /* * skb should fit one page. This choice is good for headerless malloc. * But we should limit to 8K so that userspace does not have to @@ -135,4 +161,14 @@ static inline int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, return __netlink_dump_start(ssk, skb, nlh, control); } +struct netlink_tap { + struct net_device *dev; + struct module *module; + struct list_head list; +}; + +extern int netlink_add_tap(struct netlink_tap *nt); +extern int __netlink_remove_tap(struct netlink_tap *nt); +extern int netlink_remove_tap(struct netlink_tap *nt); + #endif /* __LINUX_NETLINK_H */ diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 9d7d8c64f7c8..f3c7c24bec1c 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -40,7 +40,7 @@ struct netpoll_info { unsigned long rx_flags; spinlock_t rx_lock; - struct mutex dev_lock; + struct semaphore dev_lock; struct list_head rx_np; /* netpolls that registered an rx_hook */ struct sk_buff_head neigh_tx; /* list of neigh requests to reply to */ @@ -53,10 +53,10 @@ struct netpoll_info { }; #ifdef CONFIG_NETPOLL -extern int netpoll_rx_disable(struct net_device *dev); +extern void netpoll_rx_disable(struct net_device *dev); extern void netpoll_rx_enable(struct net_device *dev); #else -static inline int netpoll_rx_disable(struct net_device *dev) { return 0; } +static inline void netpoll_rx_disable(struct net_device *dev) { return; } static inline void netpoll_rx_enable(struct net_device *dev) { return; } #endif diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 7b8fc73810ad..e36dee52f224 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -32,6 +32,15 @@ struct nfs4_acl { struct nfs4_ace aces[0]; }; +#define NFS4_MAXLABELLEN 2048 + +struct nfs4_label { + uint32_t lfs; + uint32_t pi; + u32 len; + char *label; +}; + typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier; struct nfs_stateid4 { @@ -219,6 +228,14 @@ enum nfsstat4 { NFS4ERR_REJECT_DELEG = 10085, /* on callback */ NFS4ERR_RETURNCONFLICT = 10086, /* outstanding layoutreturn */ NFS4ERR_DELEG_REVOKED = 10087, /* deleg./layout revoked */ + + /* nfs42 */ + NFS4ERR_PARTNER_NOTSUPP = 10088, + NFS4ERR_PARTNER_NO_AUTH = 10089, + NFS4ERR_METADATA_NOTSUPP = 10090, + NFS4ERR_OFFLOAD_DENIED = 10091, + NFS4ERR_WRONG_LFS = 10092, + NFS4ERR_BADLABEL = 10093, }; static inline bool seqid_mutating_err(u32 err) @@ -378,6 +395,7 @@ enum lock_type4 { #define FATTR4_WORD1_FS_LAYOUT_TYPES (1UL << 30) #define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) #define FATTR4_WORD2_MDSTHRESHOLD (1UL << 4) +#define FATTR4_WORD2_SECURITY_LABEL (1UL << 17) /* MDS threshold bitmap bits */ #define THRESHOLD_RD (1UL << 0) @@ -390,11 +408,15 @@ enum lock_type4 { #define NFS4_VERSION 4 #define NFS4_MINOR_VERSION 0 +#if defined(CONFIG_NFS_V4_2) +#define NFS4_MAX_MINOR_VERSION 2 +#else #if defined(CONFIG_NFS_V4_1) #define NFS4_MAX_MINOR_VERSION 1 #else #define NFS4_MAX_MINOR_VERSION 0 #endif /* CONFIG_NFS_V4_1 */ +#endif /* CONFIG_NFS_V4_2 */ #define NFS4_DEBUG 1 diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 1cc25682b20b..96235b53a3fd 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -59,11 +59,18 @@ struct nfs_lockowner { pid_t l_pid; }; +#define NFS_IO_INPROGRESS 0 +struct nfs_io_counter { + unsigned long flags; + atomic_t io_count; +}; + struct nfs_lock_context { atomic_t count; struct list_head list; struct nfs_open_context *open_context; struct nfs_lockowner lockowner; + struct nfs_io_counter io_count; }; struct nfs4_state; @@ -77,6 +84,7 @@ struct nfs_open_context { unsigned long flags; #define NFS_CONTEXT_ERROR_WRITE (0) #define NFS_CONTEXT_RESEND_WRITES (1) +#define NFS_CONTEXT_BAD (2) int error; struct list_head list; @@ -199,6 +207,7 @@ struct nfs_inode { #define NFS_INO_INVALID_ACL 0x0010 /* cached acls are invalid */ #define NFS_INO_REVAL_PAGECACHE 0x0020 /* must revalidate pagecache */ #define NFS_INO_REVAL_FORCED 0x0040 /* force revalidation ignoring a delegation */ +#define NFS_INO_INVALID_LABEL 0x0080 /* cached label is invalid */ /* * Bit offsets in flags field @@ -260,9 +269,13 @@ static inline int NFS_STALE(const struct inode *inode) return test_bit(NFS_INO_STALE, &NFS_I(inode)->flags); } -static inline int NFS_FSCACHE(const struct inode *inode) +static inline struct fscache_cookie *nfs_i_fscache(struct inode *inode) { - return test_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags); +#ifdef CONFIG_NFS_FSCACHE + return NFS_I(inode)->fscache; +#else + return NULL; +#endif } static inline __u64 NFS_FILEID(const struct inode *inode) @@ -328,7 +341,7 @@ extern void nfs_zap_mapping(struct inode *inode, struct address_space *mapping); extern void nfs_zap_caches(struct inode *); extern void nfs_invalidate_atime(struct inode *); extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *, - struct nfs_fattr *); + struct nfs_fattr *, struct nfs4_label *); extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr); @@ -339,15 +352,19 @@ extern int nfs_permission(struct inode *, int); extern int nfs_open(struct inode *, struct file *); extern int nfs_release(struct inode *, struct file *); extern int nfs_attribute_timeout(struct inode *inode); +extern int nfs_attribute_cache_expired(struct inode *inode); extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode); extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); extern int nfs_setattr(struct dentry *, struct iattr *); extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr); +extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, + struct nfs4_label *label); extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx); extern void put_nfs_open_context(struct nfs_open_context *ctx); extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode); extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode); +extern void nfs_inode_attach_open_context(struct nfs_open_context *ctx); extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx); extern struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx); extern void nfs_put_lock_context(struct nfs_lock_context *l_ctx); @@ -444,14 +461,11 @@ extern int nfs3_removexattr (struct dentry *, const char *name); /* * linux/fs/nfs/direct.c */ -extern ssize_t nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t, - unsigned long); -extern ssize_t nfs_file_direct_read(struct kiocb *iocb, - const struct iovec *iov, unsigned long nr_segs, - loff_t pos, bool uio); -extern ssize_t nfs_file_direct_write(struct kiocb *iocb, - const struct iovec *iov, unsigned long nr_segs, - loff_t pos, bool uio); +extern ssize_t nfs_direct_IO(int, struct kiocb *, struct iov_iter *, loff_t); +extern ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter, + loff_t pos); +extern ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter, + loff_t pos); /* * linux/fs/nfs/dir.c @@ -460,7 +474,8 @@ extern const struct file_operations nfs_dir_operations; extern const struct dentry_operations nfs_dentry_operations; extern void nfs_force_lookup_revalidate(struct inode *dir); -extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr); +extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, + struct nfs_fattr *fattr, struct nfs4_label *label); extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags); extern void nfs_access_zap_cache(struct inode *inode); @@ -489,9 +504,28 @@ extern int nfs_mountpoint_expiry_timeout; extern void nfs_release_automount_timer(void); /* + * linux/fs/nfs/nfs4proc.c + */ +#ifdef CONFIG_NFS_V4_SECURITY_LABEL +extern struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags); +static inline void nfs4_label_free(struct nfs4_label *label) +{ + if (label) { + kfree(label->label); + kfree(label); + } + return; +} +#else +static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; } +static inline void nfs4_label_free(void *label) {} +#endif + +/* * linux/fs/nfs/unlink.c */ extern void nfs_complete_unlink(struct dentry *dentry, struct inode *); +extern void nfs_wait_on_sillyrename(struct dentry *dentry); extern void nfs_block_sillyrename(struct dentry *dentry); extern void nfs_unblock_sillyrename(struct dentry *dentry); extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 6c6ed153a9b4..b8cedced50c9 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -40,6 +40,7 @@ struct nfs_client { #define NFS_CS_NORESVPORT 0 /* - use ephemeral src port */ #define NFS_CS_DISCRTRY 1 /* - disconnect on RPC retry */ #define NFS_CS_MIGRATION 2 /* - transparent state migr */ +#define NFS_CS_INFINITE_SLOTS 3 /* - don't limit TCP slots */ struct sockaddr_storage cl_addr; /* server identifier */ size_t cl_addrlen; char * cl_hostname; /* hostname of server */ @@ -55,6 +56,7 @@ struct nfs_client { struct rpc_cred *cl_machine_cred; #if IS_ENABLED(CONFIG_NFS_V4) + struct list_head cl_ds_clients; /* auth flavor data servers */ u64 cl_clientid; /* constant */ nfs4_verifier cl_confirm; /* Clientid verifier */ unsigned long cl_state; @@ -77,6 +79,9 @@ struct nfs_client { u32 cl_cb_ident; /* v4.0 callback identifier */ const struct nfs4_minor_version_ops *cl_mvops; + /* NFSv4.0 transport blocking */ + struct nfs4_slot_table *cl_slot_tbl; + /* The sequence id to use for the next CREATE_SESSION */ u32 cl_seqid; /* The flags used for obtaining the clientid during EXCHANGE_ID */ @@ -86,6 +91,15 @@ struct nfs_client { struct nfs41_server_owner *cl_serverowner; struct nfs41_server_scope *cl_serverscope; struct nfs41_impl_id *cl_implid; + /* nfs 4.1+ state protection modes: */ + unsigned long cl_sp4_flags; +#define NFS_SP4_MACH_CRED_MINIMAL 1 /* Minimal sp4_mach_cred - state ops + * must use machine cred */ +#define NFS_SP4_MACH_CRED_CLEANUP 2 /* CLOSE and LOCKU */ +#define NFS_SP4_MACH_CRED_SECINFO 3 /* SECINFO and SECINFO_NO_NAME */ +#define NFS_SP4_MACH_CRED_STATEID 4 /* TEST_STATEID and FREE_STATEID */ +#define NFS_SP4_MACH_CRED_WRITE 5 /* WRITE */ +#define NFS_SP4_MACH_CRED_COMMIT 6 /* COMMIT */ #endif /* CONFIG_NFS_V4 */ #ifdef CONFIG_NFS_FSCACHE @@ -145,7 +159,12 @@ struct nfs_server { u32 attr_bitmask[3];/* V4 bitmask representing the set of attributes supported on this filesystem */ - u32 cache_consistency_bitmask[2]; + u32 attr_bitmask_nl[3]; + /* V4 bitmask representing the + set of attributes supported + on this filesystem excluding + the label support bit. */ + u32 cache_consistency_bitmask[3]; /* V4 bitmask representing the subset of change attribute, size, ctime and mtime attributes supported by @@ -197,5 +216,8 @@ struct nfs_server { #define NFS_CAP_MTIME (1U << 13) #define NFS_CAP_POSIX_LOCK (1U << 14) #define NFS_CAP_UIDGID_NOMAP (1U << 15) +#define NFS_CAP_STATEID_NFSV41 (1U << 16) +#define NFS_CAP_ATOMIC_OPEN_V1 (1U << 17) +#define NFS_CAP_SECURITY_LABEL (1U << 18) #endif diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 4b993d358dad..01fd84b566f7 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -14,9 +14,6 @@ #define NFS_DEF_FILE_IO_SIZE (4096U) #define NFS_MIN_FILE_IO_SIZE (1024U) -/* Forward declaration for NFS v3 */ -struct nfs4_secinfo_flavors; - struct nfs4_string { unsigned int len; char *data; @@ -104,6 +101,7 @@ struct nfs_fattr { #define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 22) #define NFS_ATTR_FATTR_OWNER_NAME (1U << 23) #define NFS_ATTR_FATTR_GROUP_NAME (1U << 24) +#define NFS_ATTR_FATTR_V4_SECURITY_LABEL (1U << 25) #define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \ | NFS_ATTR_FATTR_MODE \ @@ -123,7 +121,8 @@ struct nfs_fattr { #define NFS_ATTR_FATTR_V3 (NFS_ATTR_FATTR \ | NFS_ATTR_FATTR_SPACE_USED) #define NFS_ATTR_FATTR_V4 (NFS_ATTR_FATTR \ - | NFS_ATTR_FATTR_SPACE_USED) + | NFS_ATTR_FATTR_SPACE_USED \ + | NFS_ATTR_FATTR_V4_SECURITY_LABEL) /* * Info on the file system @@ -249,6 +248,7 @@ struct nfs4_layoutget_res { struct nfs4_layoutget { struct nfs4_layoutget_args args; struct nfs4_layoutget_res res; + struct rpc_cred *cred; gfp_t gfp_flags; }; @@ -349,6 +349,8 @@ struct nfs_openargs { const u32 * bitmask; const u32 * open_bitmap; __u32 claim; + enum createmode4 createmode; + const struct nfs4_label *label; }; struct nfs_openres { @@ -358,6 +360,7 @@ struct nfs_openres { struct nfs4_change_info cinfo; __u32 rflags; struct nfs_fattr * f_attr; + struct nfs4_label *f_label; struct nfs_seqid * seqid; const struct nfs_server *server; fmode_t delegation_type; @@ -486,6 +489,7 @@ struct nfs_readargs { struct nfs_fh * fh; struct nfs_open_context *context; struct nfs_lock_context *lock_context; + nfs4_stateid stateid; __u64 offset; __u32 count; unsigned int pgbase; @@ -507,6 +511,7 @@ struct nfs_writeargs { struct nfs_fh * fh; struct nfs_open_context *context; struct nfs_lock_context *lock_context; + nfs4_stateid stateid; __u64 offset; __u32 count; enum nfs3_stable_how stable; @@ -598,6 +603,7 @@ struct nfs_entry { int eof; struct nfs_fh * fh; struct nfs_fattr * fattr; + struct nfs4_label *label; unsigned char d_type; struct nfs_server * server; }; @@ -630,6 +636,7 @@ struct nfs_setattrargs { struct iattr * iap; const struct nfs_server * server; /* Needed for name mapping */ const u32 * bitmask; + const struct nfs4_label *label; }; struct nfs_setaclargs { @@ -665,6 +672,7 @@ struct nfs_getaclres { struct nfs_setattrres { struct nfs4_sequence_res seq_res; struct nfs_fattr * fattr; + struct nfs4_label *label; const struct nfs_server * server; }; @@ -862,6 +870,7 @@ struct nfs4_create_arg { const struct iattr * attrs; const struct nfs_fh * dir_fh; const u32 * bitmask; + const struct nfs4_label *label; }; struct nfs4_create_res { @@ -869,6 +878,7 @@ struct nfs4_create_res { const struct nfs_server * server; struct nfs_fh * fh; struct nfs_fattr * fattr; + struct nfs4_label *label; struct nfs4_change_info dir_cinfo; }; @@ -893,6 +903,7 @@ struct nfs4_getattr_res { struct nfs4_sequence_res seq_res; const struct nfs_server * server; struct nfs_fattr * fattr; + struct nfs4_label *label; }; struct nfs4_link_arg { @@ -907,6 +918,7 @@ struct nfs4_link_res { struct nfs4_sequence_res seq_res; const struct nfs_server * server; struct nfs_fattr * fattr; + struct nfs4_label *label; struct nfs4_change_info cinfo; struct nfs_fattr * dir_attr; }; @@ -924,6 +936,7 @@ struct nfs4_lookup_res { const struct nfs_server * server; struct nfs_fattr * fattr; struct nfs_fh * fh; + struct nfs4_label *label; }; struct nfs4_lookup_root_arg { @@ -1050,25 +1063,14 @@ struct nfs4_fs_locations_res { struct nfs4_fs_locations *fs_locations; }; -struct nfs4_secinfo_oid { - unsigned int len; - char data[GSS_OID_MAX_LEN]; -}; - -struct nfs4_secinfo_gss { - struct nfs4_secinfo_oid sec_oid4; - unsigned int qop4; - unsigned int service; -}; - -struct nfs4_secinfo_flavor { - unsigned int flavor; - struct nfs4_secinfo_gss gss; +struct nfs4_secinfo4 { + u32 flavor; + struct rpcsec_gss_info flavor_info; }; struct nfs4_secinfo_flavors { - unsigned int num_flavors; - struct nfs4_secinfo_flavor flavors[0]; + unsigned int num_flavors; + struct nfs4_secinfo4 flavors[0]; }; struct nfs4_secinfo_arg { @@ -1105,6 +1107,23 @@ struct pnfs_ds_commit_info { struct pnfs_commit_bucket *buckets; }; +#define NFS4_OP_MAP_NUM_LONGS \ + DIV_ROUND_UP(LAST_NFS4_OP, 8 * sizeof(unsigned long)) +#define NFS4_OP_MAP_NUM_WORDS \ + (NFS4_OP_MAP_NUM_LONGS * sizeof(unsigned long) / sizeof(u32)) +struct nfs4_op_map { + union { + unsigned long longs[NFS4_OP_MAP_NUM_LONGS]; + u32 words[NFS4_OP_MAP_NUM_WORDS]; + } u; +}; + +struct nfs41_state_protection { + u32 how; + struct nfs4_op_map enforce; + struct nfs4_op_map allow; +}; + #define NFS4_EXCHANGE_ID_LEN (48) struct nfs41_exchange_id_args { struct nfs_client *client; @@ -1112,6 +1131,7 @@ struct nfs41_exchange_id_args { unsigned int id_len; char id[NFS4_EXCHANGE_ID_LEN]; u32 flags; + struct nfs41_state_protection state_protect; }; struct nfs41_server_owner { @@ -1144,6 +1164,7 @@ struct nfs41_exchange_id_res { struct nfs41_server_owner *server_owner; struct nfs41_server_scope *server_scope; struct nfs41_impl_id *impl_id; + struct nfs41_state_protection state_protect; }; struct nfs41_create_session_args { @@ -1187,7 +1208,7 @@ struct nfs41_test_stateid_res { struct nfs41_free_stateid_args { struct nfs4_sequence_args seq_args; - nfs4_stateid *stateid; + nfs4_stateid stateid; }; struct nfs41_free_stateid_res { @@ -1377,11 +1398,12 @@ struct nfs_rpc_ops { struct dentry *(*try_mount) (int, const char *, struct nfs_mount_info *, struct nfs_subversion *); int (*getattr) (struct nfs_server *, struct nfs_fh *, - struct nfs_fattr *); + struct nfs_fattr *, struct nfs4_label *); int (*setattr) (struct dentry *, struct nfs_fattr *, struct iattr *); int (*lookup) (struct inode *, struct qstr *, - struct nfs_fh *, struct nfs_fattr *); + struct nfs_fh *, struct nfs_fattr *, + struct nfs4_label *); int (*access) (struct inode *, struct nfs_access_entry *); int (*readlink)(struct inode *, struct page *, unsigned int, unsigned int); @@ -1416,12 +1438,12 @@ struct nfs_rpc_ops { void (*read_setup) (struct nfs_read_data *, struct rpc_message *); void (*read_pageio_init)(struct nfs_pageio_descriptor *, struct inode *, const struct nfs_pgio_completion_ops *); - void (*read_rpc_prepare)(struct rpc_task *, struct nfs_read_data *); + int (*read_rpc_prepare)(struct rpc_task *, struct nfs_read_data *); int (*read_done) (struct rpc_task *, struct nfs_read_data *); void (*write_setup) (struct nfs_write_data *, struct rpc_message *); void (*write_pageio_init)(struct nfs_pageio_descriptor *, struct inode *, int, const struct nfs_pgio_completion_ops *); - void (*write_rpc_prepare)(struct rpc_task *, struct nfs_write_data *); + int (*write_rpc_prepare)(struct rpc_task *, struct nfs_write_data *); int (*write_done) (struct rpc_task *, struct nfs_write_data *); void (*commit_setup) (struct nfs_commit_data *, struct rpc_message *); void (*commit_rpc_prepare)(struct rpc_task *, struct nfs_commit_data *); @@ -1439,7 +1461,7 @@ struct nfs_rpc_ops { struct nfs_client *(*alloc_client) (const struct nfs_client_initdata *); struct nfs_client * (*init_client) (struct nfs_client *, const struct rpc_timeout *, - const char *, rpc_authflavor_t); + const char *); void (*free_client) (struct nfs_client *); struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *); struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *, diff --git a/include/linux/nmi.h b/include/linux/nmi.h index db50840e6355..6a45fb583ff1 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -46,7 +46,7 @@ static inline bool trigger_all_cpu_backtrace(void) #ifdef CONFIG_LOCKUP_DETECTOR int hw_nmi_is_cpu_stuck(struct pt_regs *); u64 hw_nmi_get_sample_period(int watchdog_thresh); -extern int watchdog_enabled; +extern int watchdog_user_enabled; extern int watchdog_thresh; struct ctl_table; extern int proc_dowatchdog(struct ctl_table *, int , diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index 4e2cbfa640b7..58b9a02c38d2 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h @@ -98,8 +98,17 @@ typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t; extern nodemask_t _unused_nodemask_arg_; +/* + * The inline keyword gives the compiler room to decide to inline, or + * not inline a function as it sees best. However, as these functions + * are called in both __init and non-__init functions, if they are not + * inlined we will end up with a section mis-match error (of the type of + * freeable items not being freed). So we must use __always_inline here + * to fix the problem. If other functions in the future also end up in + * this situation they will also need to be annotated as __always_inline + */ #define node_set(node, dst) __node_set((node), &(dst)) -static inline void __node_set(int node, volatile nodemask_t *dstp) +static __always_inline void __node_set(int node, volatile nodemask_t *dstp) { set_bit(node, dstp->bits); } diff --git a/include/linux/notifier.h b/include/linux/notifier.h index d65746efc954..d14a4c362465 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -47,8 +47,11 @@ * runtime initialization. */ +typedef int (*notifier_fn_t)(struct notifier_block *nb, + unsigned long action, void *data); + struct notifier_block { - int (*notifier_call)(struct notifier_block *, unsigned long, void *); + notifier_fn_t notifier_call; struct notifier_block __rcu *next; int priority; }; diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h index 10e5947491c7..b4ec59d159ac 100644 --- a/include/linux/nsproxy.h +++ b/include/linux/nsproxy.h @@ -14,6 +14,10 @@ struct fs_struct; * A structure to contain pointers to all per-process * namespaces - fs (mount), uts, network, sysvipc, etc. * + * The pid namespace is an exception -- it's accessed using + * task_active_pid_ns. The pid namespace here is the + * namespace that children will use. + * * 'count' is the number of tasks holding a reference. * The count for each namespace, then, will be the number * of nsproxies pointing to it, not the number of tasks. @@ -27,7 +31,7 @@ struct nsproxy { struct uts_namespace *uts_ns; struct ipc_namespace *ipc_ns; struct mnt_namespace *mnt_ns; - struct pid_namespace *pid_ns; + struct pid_namespace *pid_ns_for_children; struct net *net_ns; }; extern struct nsproxy init_nsproxy; diff --git a/include/linux/nubus.h b/include/linux/nubus.h index a8696bbdfbc4..6165b2c62040 100644 --- a/include/linux/nubus.h +++ b/include/linux/nubus.h @@ -80,10 +80,13 @@ extern struct nubus_board* nubus_boards; /* Generic NuBus interface functions, modelled after the PCI interface */ void nubus_scan_bus(void); +#ifdef CONFIG_PROC_FS extern void nubus_proc_init(void); +#else +static inline void nubus_proc_init(void) {} +#endif int get_nubus_list(char *buf); int nubus_proc_attach_device(struct nubus_dev *dev); -int nubus_proc_detach_device(struct nubus_dev *dev); /* If we need more precision we can add some more of these */ struct nubus_dev* nubus_find_device(unsigned short category, unsigned short type, diff --git a/include/linux/nvme.h b/include/linux/nvme.h index c25cccaa555a..26ebcf41c213 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -1,6 +1,6 @@ /* * Definitions for the NVM Express interface - * Copyright (c) 2011, Intel Corporation. + * Copyright (c) 2011-2013, 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, @@ -19,7 +19,10 @@ #ifndef _LINUX_NVME_H #define _LINUX_NVME_H -#include <linux/types.h> +#include <uapi/linux/nvme.h> +#include <linux/pci.h> +#include <linux/miscdevice.h> +#include <linux/kref.h> struct nvme_bar { __u64 cap; /* Controller Capabilities */ @@ -50,6 +53,7 @@ enum { NVME_CC_SHN_NONE = 0 << 14, NVME_CC_SHN_NORMAL = 1 << 14, NVME_CC_SHN_ABRUPT = 2 << 14, + NVME_CC_SHN_MASK = 3 << 14, NVME_CC_IOSQES = 6 << 16, NVME_CC_IOCQES = 4 << 20, NVME_CSTS_RDY = 1 << 0, @@ -57,380 +61,110 @@ enum { NVME_CSTS_SHST_NORMAL = 0 << 2, NVME_CSTS_SHST_OCCUR = 1 << 2, NVME_CSTS_SHST_CMPLT = 2 << 2, -}; - -struct nvme_id_power_state { - __le16 max_power; /* centiwatts */ - __u16 rsvd2; - __le32 entry_lat; /* microseconds */ - __le32 exit_lat; /* microseconds */ - __u8 read_tput; - __u8 read_lat; - __u8 write_tput; - __u8 write_lat; - __u8 rsvd16[16]; + NVME_CSTS_SHST_MASK = 3 << 2, }; #define NVME_VS(major, minor) (major << 16 | minor) -struct nvme_id_ctrl { - __le16 vid; - __le16 ssvid; - char sn[20]; - char mn[40]; - char fr[8]; - __u8 rab; - __u8 ieee[3]; - __u8 mic; - __u8 mdts; - __u8 rsvd78[178]; - __le16 oacs; - __u8 acl; - __u8 aerl; - __u8 frmw; - __u8 lpa; - __u8 elpe; - __u8 npss; - __u8 rsvd264[248]; - __u8 sqes; - __u8 cqes; - __u8 rsvd514[2]; - __le32 nn; - __le16 oncs; - __le16 fuses; - __u8 fna; - __u8 vwc; - __le16 awun; - __le16 awupf; - __u8 rsvd530[1518]; - struct nvme_id_power_state psd[32]; - __u8 vs[1024]; -}; - -struct nvme_lbaf { - __le16 ms; - __u8 ds; - __u8 rp; -}; - -struct nvme_id_ns { - __le64 nsze; - __le64 ncap; - __le64 nuse; - __u8 nsfeat; - __u8 nlbaf; - __u8 flbas; - __u8 mc; - __u8 dpc; - __u8 dps; - __u8 rsvd30[98]; - struct nvme_lbaf lbaf[16]; - __u8 rsvd192[192]; - __u8 vs[3712]; -}; - -enum { - NVME_NS_FEAT_THIN = 1 << 0, - NVME_LBAF_RP_BEST = 0, - NVME_LBAF_RP_BETTER = 1, - NVME_LBAF_RP_GOOD = 2, - NVME_LBAF_RP_DEGRADED = 3, -}; - -struct nvme_lba_range_type { - __u8 type; - __u8 attributes; - __u8 rsvd2[14]; - __u64 slba; - __u64 nlb; - __u8 guid[16]; - __u8 rsvd48[16]; -}; - -enum { - NVME_LBART_TYPE_FS = 0x01, - NVME_LBART_TYPE_RAID = 0x02, - NVME_LBART_TYPE_CACHE = 0x03, - NVME_LBART_TYPE_SWAP = 0x04, - - NVME_LBART_ATTRIB_TEMP = 1 << 0, - NVME_LBART_ATTRIB_HIDE = 1 << 1, -}; - -/* I/O commands */ - -enum nvme_opcode { - nvme_cmd_flush = 0x00, - nvme_cmd_write = 0x01, - nvme_cmd_read = 0x02, - nvme_cmd_write_uncor = 0x04, - nvme_cmd_compare = 0x05, - nvme_cmd_dsm = 0x09, -}; - -struct nvme_common_command { - __u8 opcode; - __u8 flags; - __u16 command_id; - __le32 nsid; - __u32 cdw2[2]; - __le64 metadata; - __le64 prp1; - __le64 prp2; - __u32 cdw10[6]; -}; - -struct nvme_rw_command { - __u8 opcode; - __u8 flags; - __u16 command_id; - __le32 nsid; - __u64 rsvd2; - __le64 metadata; - __le64 prp1; - __le64 prp2; - __le64 slba; - __le16 length; - __le16 control; - __le32 dsmgmt; - __le32 reftag; - __le16 apptag; - __le16 appmask; -}; - -enum { - NVME_RW_LR = 1 << 15, - NVME_RW_FUA = 1 << 14, - NVME_RW_DSM_FREQ_UNSPEC = 0, - NVME_RW_DSM_FREQ_TYPICAL = 1, - NVME_RW_DSM_FREQ_RARE = 2, - NVME_RW_DSM_FREQ_READS = 3, - NVME_RW_DSM_FREQ_WRITES = 4, - NVME_RW_DSM_FREQ_RW = 5, - NVME_RW_DSM_FREQ_ONCE = 6, - NVME_RW_DSM_FREQ_PREFETCH = 7, - NVME_RW_DSM_FREQ_TEMP = 8, - NVME_RW_DSM_LATENCY_NONE = 0 << 4, - NVME_RW_DSM_LATENCY_IDLE = 1 << 4, - NVME_RW_DSM_LATENCY_NORM = 2 << 4, - NVME_RW_DSM_LATENCY_LOW = 3 << 4, - NVME_RW_DSM_SEQ_REQ = 1 << 6, - NVME_RW_DSM_COMPRESSED = 1 << 7, -}; - -/* Admin commands */ - -enum nvme_admin_opcode { - nvme_admin_delete_sq = 0x00, - nvme_admin_create_sq = 0x01, - nvme_admin_get_log_page = 0x02, - nvme_admin_delete_cq = 0x04, - nvme_admin_create_cq = 0x05, - nvme_admin_identify = 0x06, - nvme_admin_abort_cmd = 0x08, - nvme_admin_set_features = 0x09, - nvme_admin_get_features = 0x0a, - nvme_admin_async_event = 0x0c, - nvme_admin_activate_fw = 0x10, - nvme_admin_download_fw = 0x11, - nvme_admin_format_nvm = 0x80, - nvme_admin_security_send = 0x81, - nvme_admin_security_recv = 0x82, -}; - -enum { - NVME_QUEUE_PHYS_CONTIG = (1 << 0), - NVME_CQ_IRQ_ENABLED = (1 << 1), - NVME_SQ_PRIO_URGENT = (0 << 1), - NVME_SQ_PRIO_HIGH = (1 << 1), - NVME_SQ_PRIO_MEDIUM = (2 << 1), - NVME_SQ_PRIO_LOW = (3 << 1), - NVME_FEAT_ARBITRATION = 0x01, - NVME_FEAT_POWER_MGMT = 0x02, - NVME_FEAT_LBA_RANGE = 0x03, - NVME_FEAT_TEMP_THRESH = 0x04, - NVME_FEAT_ERR_RECOVERY = 0x05, - NVME_FEAT_VOLATILE_WC = 0x06, - NVME_FEAT_NUM_QUEUES = 0x07, - NVME_FEAT_IRQ_COALESCE = 0x08, - NVME_FEAT_IRQ_CONFIG = 0x09, - NVME_FEAT_WRITE_ATOMIC = 0x0a, - NVME_FEAT_ASYNC_EVENT = 0x0b, - NVME_FEAT_SW_PROGRESS = 0x0c, -}; - -struct nvme_identify { - __u8 opcode; - __u8 flags; - __u16 command_id; - __le32 nsid; - __u64 rsvd2[2]; - __le64 prp1; - __le64 prp2; - __le32 cns; - __u32 rsvd11[5]; -}; - -struct nvme_features { - __u8 opcode; - __u8 flags; - __u16 command_id; - __le32 nsid; - __u64 rsvd2[2]; - __le64 prp1; - __le64 prp2; - __le32 fid; - __le32 dword11; - __u32 rsvd12[4]; -}; - -struct nvme_create_cq { - __u8 opcode; - __u8 flags; - __u16 command_id; - __u32 rsvd1[5]; - __le64 prp1; - __u64 rsvd8; - __le16 cqid; - __le16 qsize; - __le16 cq_flags; - __le16 irq_vector; - __u32 rsvd12[4]; -}; - -struct nvme_create_sq { - __u8 opcode; - __u8 flags; - __u16 command_id; - __u32 rsvd1[5]; - __le64 prp1; - __u64 rsvd8; - __le16 sqid; - __le16 qsize; - __le16 sq_flags; - __le16 cqid; - __u32 rsvd12[4]; -}; - -struct nvme_delete_queue { - __u8 opcode; - __u8 flags; - __u16 command_id; - __u32 rsvd1[9]; - __le16 qid; - __u16 rsvd10; - __u32 rsvd11[5]; -}; +#define NVME_IO_TIMEOUT (5 * HZ) -struct nvme_download_firmware { - __u8 opcode; - __u8 flags; - __u16 command_id; - __u32 rsvd1[5]; - __le64 prp1; - __le64 prp2; - __le32 numd; - __le32 offset; - __u32 rsvd12[4]; -}; - -struct nvme_command { - union { - struct nvme_common_command common; - struct nvme_rw_command rw; - struct nvme_identify identify; - struct nvme_features features; - struct nvme_create_cq create_cq; - struct nvme_create_sq create_sq; - struct nvme_delete_queue delete_queue; - struct nvme_download_firmware dlfw; - }; -}; - -enum { - NVME_SC_SUCCESS = 0x0, - NVME_SC_INVALID_OPCODE = 0x1, - NVME_SC_INVALID_FIELD = 0x2, - NVME_SC_CMDID_CONFLICT = 0x3, - NVME_SC_DATA_XFER_ERROR = 0x4, - NVME_SC_POWER_LOSS = 0x5, - NVME_SC_INTERNAL = 0x6, - NVME_SC_ABORT_REQ = 0x7, - NVME_SC_ABORT_QUEUE = 0x8, - NVME_SC_FUSED_FAIL = 0x9, - NVME_SC_FUSED_MISSING = 0xa, - NVME_SC_INVALID_NS = 0xb, - NVME_SC_LBA_RANGE = 0x80, - NVME_SC_CAP_EXCEEDED = 0x81, - NVME_SC_NS_NOT_READY = 0x82, - NVME_SC_CQ_INVALID = 0x100, - NVME_SC_QID_INVALID = 0x101, - NVME_SC_QUEUE_SIZE = 0x102, - NVME_SC_ABORT_LIMIT = 0x103, - NVME_SC_ABORT_MISSING = 0x104, - NVME_SC_ASYNC_LIMIT = 0x105, - NVME_SC_FIRMWARE_SLOT = 0x106, - NVME_SC_FIRMWARE_IMAGE = 0x107, - NVME_SC_INVALID_VECTOR = 0x108, - NVME_SC_INVALID_LOG_PAGE = 0x109, - NVME_SC_INVALID_FORMAT = 0x10a, - NVME_SC_BAD_ATTRIBUTES = 0x180, - NVME_SC_WRITE_FAULT = 0x280, - NVME_SC_READ_ERROR = 0x281, - NVME_SC_GUARD_CHECK = 0x282, - NVME_SC_APPTAG_CHECK = 0x283, - NVME_SC_REFTAG_CHECK = 0x284, - NVME_SC_COMPARE_FAILED = 0x285, - NVME_SC_ACCESS_DENIED = 0x286, +/* + * Represents an NVM Express device. Each nvme_dev is a PCI function. + */ +struct nvme_dev { + struct list_head node; + struct nvme_queue **queues; + u32 __iomem *dbs; + struct pci_dev *pci_dev; + struct dma_pool *prp_page_pool; + struct dma_pool *prp_small_pool; + int instance; + int queue_count; + int db_stride; + u32 ctrl_config; + struct msix_entry *entry; + struct nvme_bar __iomem *bar; + struct list_head namespaces; + struct kref kref; + struct miscdevice miscdev; + char name[12]; + char serial[20]; + char model[40]; + char firmware_rev[8]; + u32 max_hw_sectors; + u32 stripe_size; + u16 oncs; }; -struct nvme_completion { - __le32 result; /* Used by admin commands to return data */ - __u32 rsvd; - __le16 sq_head; /* how much of this queue may be reclaimed */ - __le16 sq_id; /* submission queue that generated this entry */ - __u16 command_id; /* of the command which completed */ - __le16 status; /* did the command fail, and if so, why? */ -}; +/* + * An NVM Express namespace is equivalent to a SCSI LUN + */ +struct nvme_ns { + struct list_head list; -struct nvme_user_io { - __u8 opcode; - __u8 flags; - __u16 control; - __u16 nblocks; - __u16 rsvd; - __u64 metadata; - __u64 addr; - __u64 slba; - __u32 dsmgmt; - __u32 reftag; - __u16 apptag; - __u16 appmask; -}; + struct nvme_dev *dev; + struct request_queue *queue; + struct gendisk *disk; -struct nvme_admin_cmd { - __u8 opcode; - __u8 flags; - __u16 rsvd1; - __u32 nsid; - __u32 cdw2; - __u32 cdw3; - __u64 metadata; - __u64 addr; - __u32 metadata_len; - __u32 data_len; - __u32 cdw10; - __u32 cdw11; - __u32 cdw12; - __u32 cdw13; - __u32 cdw14; - __u32 cdw15; - __u32 timeout_ms; - __u32 result; + unsigned ns_id; + int lba_shift; + int ms; + u64 mode_select_num_blocks; + u32 mode_select_block_len; }; -#define NVME_IOCTL_ID _IO('N', 0x40) -#define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_admin_cmd) -#define NVME_IOCTL_SUBMIT_IO _IOW('N', 0x42, struct nvme_user_io) +/* + * The nvme_iod describes the data in an I/O, including the list of PRP + * entries. You can't see it in this data structure because C doesn't let + * me express that. Use nvme_alloc_iod to ensure there's enough space + * allocated to store the PRP list. + */ +struct nvme_iod { + void *private; /* For the use of the submitter of the I/O */ + int npages; /* In the PRP list. 0 means small pool in use */ + int offset; /* Of PRP list */ + int nents; /* Used in scatterlist */ + int length; /* Of data, in bytes */ + unsigned long start_time; + dma_addr_t first_dma; + struct scatterlist sg[0]; +}; + +static inline u64 nvme_block_nr(struct nvme_ns *ns, sector_t sector) +{ + return (sector >> (ns->lba_shift - 9)); +} + +/** + * nvme_free_iod - frees an nvme_iod + * @dev: The device that the I/O was submitted to + * @iod: The memory to free + */ +void nvme_free_iod(struct nvme_dev *dev, struct nvme_iod *iod); + +int nvme_setup_prps(struct nvme_dev *dev, struct nvme_common_command *cmd, + struct nvme_iod *iod, int total_len, gfp_t gfp); +struct nvme_iod *nvme_map_user_pages(struct nvme_dev *dev, int write, + unsigned long addr, unsigned length); +void nvme_unmap_user_pages(struct nvme_dev *dev, int write, + struct nvme_iod *iod); +struct nvme_queue *get_nvmeq(struct nvme_dev *dev); +void put_nvmeq(struct nvme_queue *nvmeq); +int nvme_submit_sync_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd, + u32 *result, unsigned timeout); +int nvme_submit_flush_data(struct nvme_queue *nvmeq, struct nvme_ns *ns); +int nvme_submit_admin_cmd(struct nvme_dev *, struct nvme_command *, + u32 *result); +int nvme_identify(struct nvme_dev *, unsigned nsid, unsigned cns, + dma_addr_t dma_addr); +int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, + dma_addr_t dma_addr, u32 *result); +int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11, + dma_addr_t dma_addr, u32 *result); + +struct sg_io_hdr; + +int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr); +int nvme_sg_get_version_num(int __user *ip); #endif /* _LINUX_NVME_H */ diff --git a/include/linux/of.h b/include/linux/of.h index a0f129284948..f95aee391e30 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -235,6 +235,9 @@ extern struct device_node *of_find_node_with_property( extern struct property *of_find_property(const struct device_node *np, const char *name, int *lenp); +extern int of_property_read_u32_index(const struct device_node *np, + const char *propname, + u32 index, u32 *out_value); extern int of_property_read_u8_array(const struct device_node *np, const char *propname, u8 *out_values, size_t sz); extern int of_property_read_u16_array(const struct device_node *np, @@ -263,6 +266,7 @@ extern int of_device_is_available(const struct device_node *device); extern const void *of_get_property(const struct device_node *node, const char *name, int *lenp); +extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); #define for_each_property_of_node(dn, pp) \ for (pp = dn->properties; pp != NULL; pp = pp->next) @@ -277,6 +281,9 @@ extern struct device_node *of_parse_phandle(const struct device_node *np, extern int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name, int index, struct of_phandle_args *out_args); +extern int of_parse_phandle_with_fixed_args(const struct device_node *np, + const char *list_name, int cells_count, int index, + struct of_phandle_args *out_args); extern int of_count_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name); @@ -320,12 +327,6 @@ extern int of_detach_node(struct device_node *); */ const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, u32 *pu); -#define of_property_for_each_u32(np, propname, prop, p, u) \ - for (prop = of_find_property(np, propname, NULL), \ - p = of_prop_next_u32(prop, NULL, &u); \ - p; \ - p = of_prop_next_u32(prop, p, &u)) - /* * struct property *prop; * const char *s; @@ -334,11 +335,8 @@ const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, * printk("String value: %s\n", s); */ const char *of_prop_next_string(struct property *prop, const char *cur); -#define of_property_for_each_string(np, propname, prop, s) \ - for (prop = of_find_property(np, propname, NULL), \ - s = of_prop_next_string(prop, NULL); \ - s; \ - s = of_prop_next_string(prop, s)) + +int of_device_is_stdout_path(struct device_node *dn); #else /* CONFIG_OF */ @@ -353,6 +351,11 @@ static inline struct device_node *of_find_node_by_name(struct device_node *from, return NULL; } +static inline struct device_node *of_get_parent(const struct device_node *node) +{ + return NULL; +} + static inline bool of_have_populated_dt(void) { return false; @@ -379,6 +382,11 @@ static inline int of_device_is_compatible(const struct device_node *device, return 0; } +static inline int of_device_is_available(const struct device_node *device) +{ + return 0; +} + static inline struct property *of_find_property(const struct device_node *np, const char *name, int *lenp) @@ -394,6 +402,12 @@ static inline struct device_node *of_find_compatible_node( return NULL; } +static inline int of_property_read_u32_index(const struct device_node *np, + const char *propname, u32 index, u32 *out_value) +{ + return -ENOSYS; +} + static inline int of_property_read_u8_array(const struct device_node *np, const char *propname, u8 *out_values, size_t sz) { @@ -440,6 +454,12 @@ static inline const void *of_get_property(const struct device_node *node, return NULL; } +static inline struct device_node *of_get_cpu_node(int cpu, + unsigned int *thread) +{ + return NULL; +} + static inline int of_property_read_u64(const struct device_node *np, const char *propname, u64 *out_value) { @@ -469,6 +489,13 @@ static inline int of_parse_phandle_with_args(struct device_node *np, return -ENOSYS; } +static inline int of_parse_phandle_with_fixed_args(const struct device_node *np, + const char *list_name, int cells_count, int index, + struct of_phandle_args *out_args) +{ + return -ENOSYS; +} + static inline int of_count_phandle_with_args(struct device_node *np, const char *list_name, const char *cells_name) @@ -486,12 +513,25 @@ static inline int of_machine_is_compatible(const char *compat) return 0; } +static inline int of_device_is_stdout_path(struct device_node *dn) +{ + return 0; +} + +static inline const __be32 *of_prop_next_u32(struct property *prop, + const __be32 *cur, u32 *pu) +{ + return NULL; +} + +static inline const char *of_prop_next_string(struct property *prop, + const char *cur) +{ + return NULL; +} + #define of_match_ptr(_ptr) NULL #define of_match_node(_matches, _node) NULL -#define of_property_for_each_u32(np, propname, prop, p, u) \ - while (0) -#define of_property_for_each_string(np, propname, prop, s) \ - while (0) #endif /* CONFIG_OF */ #ifndef of_node_to_nid @@ -540,4 +580,26 @@ static inline int of_property_read_u32(const struct device_node *np, return of_property_read_u32_array(np, propname, out_value, 1); } +#define of_property_for_each_u32(np, propname, prop, p, u) \ + for (prop = of_find_property(np, propname, NULL), \ + p = of_prop_next_u32(prop, NULL, &u); \ + p; \ + p = of_prop_next_u32(prop, p, &u)) + +#define of_property_for_each_string(np, propname, prop, s) \ + for (prop = of_find_property(np, propname, NULL), \ + s = of_prop_next_string(prop, NULL); \ + s; \ + s = of_prop_next_string(prop, s)) + +#if defined(CONFIG_PROC_FS) && defined(CONFIG_PROC_DEVICETREE) +extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *); +extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop); +extern void proc_device_tree_remove_prop(struct proc_dir_entry *pde, + struct property *prop); +extern void proc_device_tree_update_prop(struct proc_dir_entry *pde, + struct property *newprop, + struct property *oldprop); +#endif + #endif /* _LINUX_OF_H */ diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 0506eb53519b..4c2e6f26432c 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -4,6 +4,36 @@ #include <linux/errno.h> #include <linux/of.h> +struct of_pci_range_parser { + struct device_node *node; + const __be32 *range; + const __be32 *end; + int np; + int pna; +}; + +struct of_pci_range { + u32 pci_space; + u64 pci_addr; + u64 cpu_addr; + u64 size; + u32 flags; +}; + +#define for_each_of_pci_range(parser, range) \ + for (; of_pci_range_parser_one(parser, range);) + +static inline void of_pci_range_to_resource(struct of_pci_range *range, + struct device_node *np, + struct resource *res) +{ + res->flags = range->flags; + res->start = range->cpu_addr; + res->end = range->cpu_addr + range->size - 1; + res->parent = res->child = res->sibling = NULL; + res->name = np->full_name; +} + #ifdef CONFIG_OF_ADDRESS extern u64 of_translate_address(struct device_node *np, const __be32 *addr); extern bool of_can_translate_address(struct device_node *dev); @@ -27,6 +57,11 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } #define pci_address_to_pio pci_address_to_pio #endif +extern int of_pci_range_parser_init(struct of_pci_range_parser *parser, + struct device_node *node); +extern struct of_pci_range *of_pci_range_parser_one( + struct of_pci_range_parser *parser, + struct of_pci_range *range); #else /* CONFIG_OF_ADDRESS */ #ifndef of_address_to_resource static inline int of_address_to_resource(struct device_node *dev, int index, @@ -53,6 +88,19 @@ static inline const __be32 *of_get_address(struct device_node *dev, int index, { return NULL; } + +static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser, + struct device_node *node) +{ + return -1; +} + +static inline struct of_pci_range *of_pci_range_parser_one( + struct of_pci_range_parser *parser, + struct of_pci_range *range) +{ + return NULL; +} #endif /* CONFIG_OF_ADDRESS */ diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 901b7435e890..82ce324fdce7 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -1,15 +1,16 @@ #ifndef _LINUX_OF_DEVICE_H #define _LINUX_OF_DEVICE_H +#include <linux/cpu.h> #include <linux/platform_device.h> #include <linux/of_platform.h> /* temporary until merge */ -#ifdef CONFIG_OF_DEVICE #include <linux/of.h> #include <linux/mod_devicetable.h> struct device; +#ifdef CONFIG_OF extern const struct of_device_id *of_match_device( const struct of_device_id *matches, const struct device *dev); extern void of_device_make_bus_id(struct device *dev); @@ -43,7 +44,16 @@ static inline void of_device_node_put(struct device *dev) of_node_put(dev->of_node); } -#else /* CONFIG_OF_DEVICE */ +static inline struct device_node *of_cpu_device_node_get(int cpu) +{ + struct device *cpu_dev; + cpu_dev = get_cpu_device(cpu); + if (!cpu_dev) + return NULL; + return of_node_get(cpu_dev->of_node); +} + +#else /* CONFIG_OF */ static inline int of_driver_match_device(struct device *dev, struct device_driver *drv) @@ -67,6 +77,11 @@ static inline const struct of_device_id *of_match_device( { return NULL; } -#endif /* CONFIG_OF_DEVICE */ + +static inline struct device_node *of_cpu_device_node_get(int cpu) +{ + return NULL; +} +#endif /* CONFIG_OF */ #endif /* _LINUX_OF_DEVICE_H */ diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h index d15073e080dd..ae36298ba076 100644 --- a/include/linux/of_dma.h +++ b/include/linux/of_dma.h @@ -21,11 +21,9 @@ struct device_node; struct of_dma { struct list_head of_dma_controllers; struct device_node *of_node; - int of_dma_nbcells; struct dma_chan *(*of_dma_xlate) (struct of_phandle_args *, struct of_dma *); void *of_dma_data; - int use_count; }; struct of_dma_filter_info { @@ -38,9 +36,9 @@ extern int of_dma_controller_register(struct device_node *np, struct dma_chan *(*of_dma_xlate) (struct of_phandle_args *, struct of_dma *), void *data); -extern int of_dma_controller_free(struct device_node *np); +extern void of_dma_controller_free(struct device_node *np); extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np, - char *name); + const char *name); extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma); #else @@ -52,13 +50,12 @@ static inline int of_dma_controller_register(struct device_node *np, return -ENODEV; } -static inline int of_dma_controller_free(struct device_node *np) +static inline void of_dma_controller_free(struct device_node *np) { - return -ENODEV; } static inline struct dma_chan *of_dma_request_slave_channel(struct device_node *np, - char *name) + const char *name) { return NULL; } diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index ed136ad698ce..a478c62a2aab 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -90,6 +90,9 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name, extern int of_flat_dt_is_compatible(unsigned long node, const char *name); extern int of_flat_dt_match(unsigned long node, const char *const *matches); extern unsigned long of_get_flat_dt_root(void); +extern int of_scan_flat_dt_by_path(const char *path, + int (*it)(unsigned long node, const char *name, int depth, void *data), + void *data); extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, int depth, void *data); @@ -106,8 +109,7 @@ extern u64 dt_mem_next_cell(int s, __be32 **cellp); * physical addresses. */ #ifdef CONFIG_BLK_DEV_INITRD -extern void early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end); +extern void early_init_dt_setup_initrd_arch(u64 start, u64 end); #endif /* Early flat tree scan hooks */ diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h deleted file mode 100644 index cfb545cd86b5..000000000000 --- a/include/linux/of_i2c.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Generic I2C API implementation for PowerPC. - * - * Copyright (c) 2008 Jochen Friedrich <jochen@scram.de> - * - * 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_I2C_H -#define __LINUX_OF_I2C_H - -#if defined(CONFIG_OF_I2C) || defined(CONFIG_OF_I2C_MODULE) -#include <linux/i2c.h> - -extern void of_i2c_register_devices(struct i2c_adapter *adap); - -/* must call put_device() when done with returned i2c_client device */ -extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); - -/* must call put_device() when done with returned i2c_adapter device */ -extern struct i2c_adapter *of_find_i2c_adapter_by_node( - struct device_node *node); - -#else -static inline void of_i2c_register_devices(struct i2c_adapter *adap) -{ - return; -} - -static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) -{ - return NULL; -} - -/* must call put_device() when done with returned i2c_adapter device */ -static inline struct i2c_adapter *of_find_i2c_adapter_by_node( - struct device_node *node) -{ - return NULL; -} -#endif /* CONFIG_OF_I2C */ - -#endif /* __LINUX_OF_I2C_H */ diff --git a/include/linux/of_mtd.h b/include/linux/of_mtd.h index ed7f267e6389..6f10e938ff7e 100644 --- a/include/linux/of_mtd.h +++ b/include/linux/of_mtd.h @@ -10,10 +10,29 @@ #define __LINUX_OF_NET_H #ifdef CONFIG_OF_MTD + #include <linux/of.h> int of_get_nand_ecc_mode(struct device_node *np); int of_get_nand_bus_width(struct device_node *np); bool of_get_nand_on_flash_bbt(struct device_node *np); -#endif + +#else /* CONFIG_OF_MTD */ + +static inline int of_get_nand_ecc_mode(struct device_node *np) +{ + return -ENOSYS; +} + +static inline int of_get_nand_bus_width(struct device_node *np) +{ + return -ENOSYS; +} + +static inline bool of_get_nand_on_flash_bbt(struct device_node *np) +{ + return false; +} + +#endif /* CONFIG_OF_MTD */ #endif /* __LINUX_OF_MTD_H */ diff --git a/include/linux/of_net.h b/include/linux/of_net.h index f47464188710..34597c8c1a4c 100644 --- a/include/linux/of_net.h +++ b/include/linux/of_net.h @@ -9,8 +9,18 @@ #ifdef CONFIG_OF_NET #include <linux/of.h> -extern const int of_get_phy_mode(struct device_node *np); +extern int of_get_phy_mode(struct device_node *np); extern const void *of_get_mac_address(struct device_node *np); +#else +static inline int of_get_phy_mode(struct device_node *np) +{ + return -ENODEV; +} + +static inline const void *of_get_mac_address(struct device_node *np) +{ + return NULL; +} #endif #endif /* __LINUX_OF_NET_H */ diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index bb115deb7612..fd9c408631a0 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h @@ -2,6 +2,7 @@ #define __OF_PCI_H #include <linux/pci.h> +#include <linux/msi.h> struct pci_dev; struct of_irq; @@ -10,5 +11,18 @@ int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq); struct device_node; struct device_node *of_pci_find_child_device(struct device_node *parent, unsigned int devfn); +int of_pci_get_devfn(struct device_node *np); +int of_pci_parse_bus_range(struct device_node *node, struct resource *res); + +#if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI) +int of_pci_msi_chip_add(struct msi_chip *chip); +void of_pci_msi_chip_remove(struct msi_chip *chip); +struct msi_chip *of_pci_find_msi_chip_by_node(struct device_node *of_node); +#else +static inline int of_pci_msi_chip_add(struct msi_chip *chip) { return -EINVAL; } +static inline void of_pci_msi_chip_remove(struct msi_chip *chip) { } +static inline struct msi_chip * +of_pci_find_msi_chip_by_node(struct device_node *of_node) { return NULL; } +#endif #endif diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 3863a4dbdf18..05cb4a928252 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -11,7 +11,6 @@ * */ -#ifdef CONFIG_OF_DEVICE #include <linux/device.h> #include <linux/mod_devicetable.h> #include <linux/pm.h> @@ -52,27 +51,6 @@ struct of_dev_auxdata { { .compatible = _compat, .phys_addr = _phys, .name = _name, \ .platform_data = _pdata } -/** - * of_platform_driver - Legacy of-aware driver for platform devices. - * - * An of_platform_driver driver is attached to a basic platform_device on - * the ibm ebus (ibmebus_bus_type). - */ -struct of_platform_driver -{ - int (*probe)(struct platform_device* dev, - const struct of_device_id *match); - int (*remove)(struct platform_device* dev); - - int (*suspend)(struct platform_device* dev, pm_message_t state); - int (*resume)(struct platform_device* dev); - int (*shutdown)(struct platform_device* dev); - - struct device_driver driver; -}; -#define to_of_platform_driver(drv) \ - container_of(drv,struct of_platform_driver, driver) - extern const struct of_device_id of_default_bus_match_table[]; /* Platform drivers register/unregister */ @@ -81,7 +59,6 @@ extern struct platform_device *of_device_alloc(struct device_node *np, struct device *parent); extern struct platform_device *of_find_device_by_node(struct device_node *np); -#ifdef CONFIG_OF_ADDRESS /* device reg helpers depend on OF_ADDRESS */ /* Platform devices and busses creation */ extern struct platform_device *of_platform_device_create(struct device_node *np, const char *bus_id, @@ -90,17 +67,12 @@ extern struct platform_device *of_platform_device_create(struct device_node *np, extern int of_platform_bus_probe(struct device_node *root, const struct of_device_id *matches, struct device *parent); +#ifdef CONFIG_OF_ADDRESS extern int of_platform_populate(struct device_node *root, const struct of_device_id *matches, const struct of_dev_auxdata *lookup, struct device *parent); -#endif /* CONFIG_OF_ADDRESS */ - -#endif /* CONFIG_OF_DEVICE */ - -#if !defined(CONFIG_OF_ADDRESS) -struct of_dev_auxdata; -struct device; +#else static inline int of_platform_populate(struct device_node *root, const struct of_device_id *matches, const struct of_dev_auxdata *lookup, @@ -108,6 +80,6 @@ static inline int of_platform_populate(struct device_node *root, { return -ENODEV; } -#endif /* !CONFIG_OF_ADDRESS */ +#endif #endif /* _LINUX_OF_PLATFORM_H */ diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h new file mode 100644 index 000000000000..c84128255814 --- /dev/null +++ b/include/linux/of_reserved_mem.h @@ -0,0 +1,14 @@ +#ifndef __OF_RESERVED_MEM_H +#define __OF_RESERVED_MEM_H + +#ifdef CONFIG_OF_RESERVED_MEM +void of_reserved_mem_device_init(struct device *dev); +void of_reserved_mem_device_release(struct device *dev); +void early_init_dt_scan_reserved_mem(void); +#else +static inline void of_reserved_mem_device_init(struct device *dev) { } +static inline void of_reserved_mem_device_release(struct device *dev) { } +static inline void early_init_dt_scan_reserved_mem(void) { } +#endif + +#endif /* __OF_RESERVED_MEM_H */ diff --git a/include/linux/olpc-ec.h b/include/linux/olpc-ec.h index 5bb6e760aa61..2925df3ce78a 100644 --- a/include/linux/olpc-ec.h +++ b/include/linux/olpc-ec.h @@ -6,6 +6,7 @@ #define EC_WRITE_SCI_MASK 0x1b #define EC_WAKE_UP_WLAN 0x24 #define EC_WLAN_LEAVE_RESET 0x25 +#define EC_DCON_POWER_MODE 0x26 #define EC_READ_EB_MODE 0x2a #define EC_SET_SCI_INHIBIT 0x32 #define EC_SET_SCI_INHIBIT_RELEASE 0x34 diff --git a/include/linux/omap-mailbox.h b/include/linux/omap-mailbox.h new file mode 100644 index 000000000000..f8322d9cd235 --- /dev/null +++ b/include/linux/omap-mailbox.h @@ -0,0 +1,29 @@ +/* + * omap-mailbox: interprocessor communication module for OMAP + * + * 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 OMAP_MAILBOX_H +#define OMAP_MAILBOX_H + +typedef u32 mbox_msg_t; +struct omap_mbox; + +typedef int __bitwise omap_mbox_irq_t; +#define IRQ_TX ((__force omap_mbox_irq_t) 1) +#define IRQ_RX ((__force omap_mbox_irq_t) 2) + +int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); + +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); +void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); + +void omap_mbox_save_ctx(struct omap_mbox *mbox); +void omap_mbox_restore_ctx(struct omap_mbox *mbox); +void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq); +void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq); + +#endif /* OMAP_MAILBOX_H */ diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h index d42e174bd0c8..e6b240b6196c 100644 --- a/include/linux/openvswitch.h +++ b/include/linux/openvswitch.h @@ -19,435 +19,6 @@ #ifndef _LINUX_OPENVSWITCH_H #define _LINUX_OPENVSWITCH_H 1 -#include <linux/types.h> - -/** - * struct ovs_header - header for OVS Generic Netlink messages. - * @dp_ifindex: ifindex of local port for datapath (0 to make a request not - * specific to a datapath). - * - * Attributes following the header are specific to a particular OVS Generic - * Netlink family, but all of the OVS families use this header. - */ - -struct ovs_header { - int dp_ifindex; -}; - -/* Datapaths. */ - -#define OVS_DATAPATH_FAMILY "ovs_datapath" -#define OVS_DATAPATH_MCGROUP "ovs_datapath" -#define OVS_DATAPATH_VERSION 0x1 - -enum ovs_datapath_cmd { - OVS_DP_CMD_UNSPEC, - OVS_DP_CMD_NEW, - OVS_DP_CMD_DEL, - OVS_DP_CMD_GET, - OVS_DP_CMD_SET -}; - -/** - * enum ovs_datapath_attr - attributes for %OVS_DP_* commands. - * @OVS_DP_ATTR_NAME: Name of the network device that serves as the "local - * port". This is the name of the network device whose dp_ifindex is given in - * the &struct ovs_header. Always present in notifications. Required in - * %OVS_DP_NEW requests. May be used as an alternative to specifying - * dp_ifindex in other requests (with a dp_ifindex of 0). - * @OVS_DP_ATTR_UPCALL_PID: The Netlink socket in userspace that is initially - * set on the datapath port (for OVS_ACTION_ATTR_MISS). Only valid on - * %OVS_DP_CMD_NEW requests. A value of zero indicates that upcalls should - * not be sent. - * @OVS_DP_ATTR_STATS: Statistics about packets that have passed through the - * datapath. Always present in notifications. - * - * These attributes follow the &struct ovs_header within the Generic Netlink - * payload for %OVS_DP_* commands. - */ -enum ovs_datapath_attr { - OVS_DP_ATTR_UNSPEC, - OVS_DP_ATTR_NAME, /* name of dp_ifindex netdev */ - OVS_DP_ATTR_UPCALL_PID, /* Netlink PID to receive upcalls */ - OVS_DP_ATTR_STATS, /* struct ovs_dp_stats */ - __OVS_DP_ATTR_MAX -}; - -#define OVS_DP_ATTR_MAX (__OVS_DP_ATTR_MAX - 1) - -struct ovs_dp_stats { - __u64 n_hit; /* Number of flow table matches. */ - __u64 n_missed; /* Number of flow table misses. */ - __u64 n_lost; /* Number of misses not sent to userspace. */ - __u64 n_flows; /* Number of flows present */ -}; - -struct ovs_vport_stats { - __u64 rx_packets; /* total packets received */ - __u64 tx_packets; /* total packets transmitted */ - __u64 rx_bytes; /* total bytes received */ - __u64 tx_bytes; /* total bytes transmitted */ - __u64 rx_errors; /* bad packets received */ - __u64 tx_errors; /* packet transmit problems */ - __u64 rx_dropped; /* no space in linux buffers */ - __u64 tx_dropped; /* no space available in linux */ -}; - -/* Fixed logical ports. */ -#define OVSP_LOCAL ((__u16)0) - -/* Packet transfer. */ - -#define OVS_PACKET_FAMILY "ovs_packet" -#define OVS_PACKET_VERSION 0x1 - -enum ovs_packet_cmd { - OVS_PACKET_CMD_UNSPEC, - - /* Kernel-to-user notifications. */ - OVS_PACKET_CMD_MISS, /* Flow table miss. */ - OVS_PACKET_CMD_ACTION, /* OVS_ACTION_ATTR_USERSPACE action. */ - - /* Userspace commands. */ - OVS_PACKET_CMD_EXECUTE /* Apply actions to a packet. */ -}; - -/** - * enum ovs_packet_attr - attributes for %OVS_PACKET_* commands. - * @OVS_PACKET_ATTR_PACKET: Present for all notifications. Contains the entire - * packet as received, from the start of the Ethernet header onward. For - * %OVS_PACKET_CMD_ACTION, %OVS_PACKET_ATTR_PACKET reflects changes made by - * actions preceding %OVS_ACTION_ATTR_USERSPACE, but %OVS_PACKET_ATTR_KEY is - * the flow key extracted from the packet as originally received. - * @OVS_PACKET_ATTR_KEY: Present for all notifications. Contains the flow key - * extracted from the packet as nested %OVS_KEY_ATTR_* attributes. This allows - * userspace to adapt its flow setup strategy by comparing its notion of the - * flow key against the kernel's. - * @OVS_PACKET_ATTR_ACTIONS: Contains actions for the packet. Used - * for %OVS_PACKET_CMD_EXECUTE. It has nested %OVS_ACTION_ATTR_* attributes. - * @OVS_PACKET_ATTR_USERDATA: Present for an %OVS_PACKET_CMD_ACTION - * notification if the %OVS_ACTION_ATTR_USERSPACE action specified an - * %OVS_USERSPACE_ATTR_USERDATA attribute. - * - * These attributes follow the &struct ovs_header within the Generic Netlink - * payload for %OVS_PACKET_* commands. - */ -enum ovs_packet_attr { - OVS_PACKET_ATTR_UNSPEC, - OVS_PACKET_ATTR_PACKET, /* Packet data. */ - OVS_PACKET_ATTR_KEY, /* Nested OVS_KEY_ATTR_* attributes. */ - OVS_PACKET_ATTR_ACTIONS, /* Nested OVS_ACTION_ATTR_* attributes. */ - OVS_PACKET_ATTR_USERDATA, /* u64 OVS_ACTION_ATTR_USERSPACE arg. */ - __OVS_PACKET_ATTR_MAX -}; - -#define OVS_PACKET_ATTR_MAX (__OVS_PACKET_ATTR_MAX - 1) - -/* Virtual ports. */ - -#define OVS_VPORT_FAMILY "ovs_vport" -#define OVS_VPORT_MCGROUP "ovs_vport" -#define OVS_VPORT_VERSION 0x1 - -enum ovs_vport_cmd { - OVS_VPORT_CMD_UNSPEC, - OVS_VPORT_CMD_NEW, - OVS_VPORT_CMD_DEL, - OVS_VPORT_CMD_GET, - OVS_VPORT_CMD_SET -}; - -enum ovs_vport_type { - OVS_VPORT_TYPE_UNSPEC, - OVS_VPORT_TYPE_NETDEV, /* network device */ - OVS_VPORT_TYPE_INTERNAL, /* network device implemented by datapath */ - __OVS_VPORT_TYPE_MAX -}; - -#define OVS_VPORT_TYPE_MAX (__OVS_VPORT_TYPE_MAX - 1) - -/** - * enum ovs_vport_attr - attributes for %OVS_VPORT_* commands. - * @OVS_VPORT_ATTR_PORT_NO: 32-bit port number within datapath. - * @OVS_VPORT_ATTR_TYPE: 32-bit %OVS_VPORT_TYPE_* constant describing the type - * of vport. - * @OVS_VPORT_ATTR_NAME: Name of vport. For a vport based on a network device - * this is the name of the network device. Maximum length %IFNAMSIZ-1 bytes - * plus a null terminator. - * @OVS_VPORT_ATTR_OPTIONS: Vport-specific configuration information. - * @OVS_VPORT_ATTR_UPCALL_PID: The Netlink socket in userspace that - * OVS_PACKET_CMD_MISS upcalls will be directed to for packets received on - * this port. A value of zero indicates that upcalls should not be sent. - * @OVS_VPORT_ATTR_STATS: A &struct ovs_vport_stats giving statistics for - * packets sent or received through the vport. - * - * These attributes follow the &struct ovs_header within the Generic Netlink - * payload for %OVS_VPORT_* commands. - * - * For %OVS_VPORT_CMD_NEW requests, the %OVS_VPORT_ATTR_TYPE and - * %OVS_VPORT_ATTR_NAME attributes are required. %OVS_VPORT_ATTR_PORT_NO is - * optional; if not specified a free port number is automatically selected. - * Whether %OVS_VPORT_ATTR_OPTIONS is required or optional depends on the type - * of vport. - * and other attributes are ignored. - * - * For other requests, if %OVS_VPORT_ATTR_NAME is specified then it is used to - * look up the vport to operate on; otherwise dp_idx from the &struct - * ovs_header plus %OVS_VPORT_ATTR_PORT_NO determine the vport. - */ -enum ovs_vport_attr { - OVS_VPORT_ATTR_UNSPEC, - OVS_VPORT_ATTR_PORT_NO, /* u32 port number within datapath */ - OVS_VPORT_ATTR_TYPE, /* u32 OVS_VPORT_TYPE_* constant. */ - OVS_VPORT_ATTR_NAME, /* string name, up to IFNAMSIZ bytes long */ - OVS_VPORT_ATTR_OPTIONS, /* nested attributes, varies by vport type */ - OVS_VPORT_ATTR_UPCALL_PID, /* u32 Netlink PID to receive upcalls */ - OVS_VPORT_ATTR_STATS, /* struct ovs_vport_stats */ - __OVS_VPORT_ATTR_MAX -}; - -#define OVS_VPORT_ATTR_MAX (__OVS_VPORT_ATTR_MAX - 1) - -/* Flows. */ - -#define OVS_FLOW_FAMILY "ovs_flow" -#define OVS_FLOW_MCGROUP "ovs_flow" -#define OVS_FLOW_VERSION 0x1 - -enum ovs_flow_cmd { - OVS_FLOW_CMD_UNSPEC, - OVS_FLOW_CMD_NEW, - OVS_FLOW_CMD_DEL, - OVS_FLOW_CMD_GET, - OVS_FLOW_CMD_SET -}; - -struct ovs_flow_stats { - __u64 n_packets; /* Number of matched packets. */ - __u64 n_bytes; /* Number of matched bytes. */ -}; - -enum ovs_key_attr { - OVS_KEY_ATTR_UNSPEC, - OVS_KEY_ATTR_ENCAP, /* Nested set of encapsulated attributes. */ - OVS_KEY_ATTR_PRIORITY, /* u32 skb->priority */ - OVS_KEY_ATTR_IN_PORT, /* u32 OVS dp port number */ - OVS_KEY_ATTR_ETHERNET, /* struct ovs_key_ethernet */ - OVS_KEY_ATTR_VLAN, /* be16 VLAN TCI */ - OVS_KEY_ATTR_ETHERTYPE, /* be16 Ethernet type */ - OVS_KEY_ATTR_IPV4, /* struct ovs_key_ipv4 */ - OVS_KEY_ATTR_IPV6, /* struct ovs_key_ipv6 */ - OVS_KEY_ATTR_TCP, /* struct ovs_key_tcp */ - OVS_KEY_ATTR_UDP, /* struct ovs_key_udp */ - OVS_KEY_ATTR_ICMP, /* struct ovs_key_icmp */ - OVS_KEY_ATTR_ICMPV6, /* struct ovs_key_icmpv6 */ - OVS_KEY_ATTR_ARP, /* struct ovs_key_arp */ - OVS_KEY_ATTR_ND, /* struct ovs_key_nd */ - OVS_KEY_ATTR_SKB_MARK, /* u32 skb mark */ - __OVS_KEY_ATTR_MAX -}; - -#define OVS_KEY_ATTR_MAX (__OVS_KEY_ATTR_MAX - 1) - -/** - * enum ovs_frag_type - IPv4 and IPv6 fragment type - * @OVS_FRAG_TYPE_NONE: Packet is not a fragment. - * @OVS_FRAG_TYPE_FIRST: Packet is a fragment with offset 0. - * @OVS_FRAG_TYPE_LATER: Packet is a fragment with nonzero offset. - * - * Used as the @ipv4_frag in &struct ovs_key_ipv4 and as @ipv6_frag &struct - * ovs_key_ipv6. - */ -enum ovs_frag_type { - OVS_FRAG_TYPE_NONE, - OVS_FRAG_TYPE_FIRST, - OVS_FRAG_TYPE_LATER, - __OVS_FRAG_TYPE_MAX -}; - -#define OVS_FRAG_TYPE_MAX (__OVS_FRAG_TYPE_MAX - 1) - -struct ovs_key_ethernet { - __u8 eth_src[6]; - __u8 eth_dst[6]; -}; - -struct ovs_key_ipv4 { - __be32 ipv4_src; - __be32 ipv4_dst; - __u8 ipv4_proto; - __u8 ipv4_tos; - __u8 ipv4_ttl; - __u8 ipv4_frag; /* One of OVS_FRAG_TYPE_*. */ -}; - -struct ovs_key_ipv6 { - __be32 ipv6_src[4]; - __be32 ipv6_dst[4]; - __be32 ipv6_label; /* 20-bits in least-significant bits. */ - __u8 ipv6_proto; - __u8 ipv6_tclass; - __u8 ipv6_hlimit; - __u8 ipv6_frag; /* One of OVS_FRAG_TYPE_*. */ -}; - -struct ovs_key_tcp { - __be16 tcp_src; - __be16 tcp_dst; -}; - -struct ovs_key_udp { - __be16 udp_src; - __be16 udp_dst; -}; - -struct ovs_key_icmp { - __u8 icmp_type; - __u8 icmp_code; -}; - -struct ovs_key_icmpv6 { - __u8 icmpv6_type; - __u8 icmpv6_code; -}; - -struct ovs_key_arp { - __be32 arp_sip; - __be32 arp_tip; - __be16 arp_op; - __u8 arp_sha[6]; - __u8 arp_tha[6]; -}; - -struct ovs_key_nd { - __u32 nd_target[4]; - __u8 nd_sll[6]; - __u8 nd_tll[6]; -}; - -/** - * enum ovs_flow_attr - attributes for %OVS_FLOW_* commands. - * @OVS_FLOW_ATTR_KEY: Nested %OVS_KEY_ATTR_* attributes specifying the flow - * key. Always present in notifications. Required for all requests (except - * dumps). - * @OVS_FLOW_ATTR_ACTIONS: Nested %OVS_ACTION_ATTR_* attributes specifying - * the actions to take for packets that match the key. Always present in - * notifications. Required for %OVS_FLOW_CMD_NEW requests, optional for - * %OVS_FLOW_CMD_SET requests. - * @OVS_FLOW_ATTR_STATS: &struct ovs_flow_stats giving statistics for this - * flow. Present in notifications if the stats would be nonzero. Ignored in - * requests. - * @OVS_FLOW_ATTR_TCP_FLAGS: An 8-bit value giving the OR'd value of all of the - * TCP flags seen on packets in this flow. Only present in notifications for - * TCP flows, and only if it would be nonzero. Ignored in requests. - * @OVS_FLOW_ATTR_USED: A 64-bit integer giving the time, in milliseconds on - * the system monotonic clock, at which a packet was last processed for this - * flow. Only present in notifications if a packet has been processed for this - * flow. Ignored in requests. - * @OVS_FLOW_ATTR_CLEAR: If present in a %OVS_FLOW_CMD_SET request, clears the - * last-used time, accumulated TCP flags, and statistics for this flow. - * Otherwise ignored in requests. Never present in notifications. - * - * These attributes follow the &struct ovs_header within the Generic Netlink - * payload for %OVS_FLOW_* commands. - */ -enum ovs_flow_attr { - OVS_FLOW_ATTR_UNSPEC, - OVS_FLOW_ATTR_KEY, /* Sequence of OVS_KEY_ATTR_* attributes. */ - OVS_FLOW_ATTR_ACTIONS, /* Nested OVS_ACTION_ATTR_* attributes. */ - OVS_FLOW_ATTR_STATS, /* struct ovs_flow_stats. */ - OVS_FLOW_ATTR_TCP_FLAGS, /* 8-bit OR'd TCP flags. */ - OVS_FLOW_ATTR_USED, /* u64 msecs last used in monotonic time. */ - OVS_FLOW_ATTR_CLEAR, /* Flag to clear stats, tcp_flags, used. */ - __OVS_FLOW_ATTR_MAX -}; - -#define OVS_FLOW_ATTR_MAX (__OVS_FLOW_ATTR_MAX - 1) - -/** - * enum ovs_sample_attr - Attributes for %OVS_ACTION_ATTR_SAMPLE action. - * @OVS_SAMPLE_ATTR_PROBABILITY: 32-bit fraction of packets to sample with - * @OVS_ACTION_ATTR_SAMPLE. A value of 0 samples no packets, a value of - * %UINT32_MAX samples all packets and intermediate values sample intermediate - * fractions of packets. - * @OVS_SAMPLE_ATTR_ACTIONS: Set of actions to execute in sampling event. - * Actions are passed as nested attributes. - * - * Executes the specified actions with the given probability on a per-packet - * basis. - */ -enum ovs_sample_attr { - OVS_SAMPLE_ATTR_UNSPEC, - OVS_SAMPLE_ATTR_PROBABILITY, /* u32 number */ - OVS_SAMPLE_ATTR_ACTIONS, /* Nested OVS_ACTION_ATTR_* attributes. */ - __OVS_SAMPLE_ATTR_MAX, -}; - -#define OVS_SAMPLE_ATTR_MAX (__OVS_SAMPLE_ATTR_MAX - 1) - -/** - * enum ovs_userspace_attr - Attributes for %OVS_ACTION_ATTR_USERSPACE action. - * @OVS_USERSPACE_ATTR_PID: u32 Netlink PID to which the %OVS_PACKET_CMD_ACTION - * message should be sent. Required. - * @OVS_USERSPACE_ATTR_USERDATA: If present, its u64 argument is copied to the - * %OVS_PACKET_CMD_ACTION message as %OVS_PACKET_ATTR_USERDATA, - */ -enum ovs_userspace_attr { - OVS_USERSPACE_ATTR_UNSPEC, - OVS_USERSPACE_ATTR_PID, /* u32 Netlink PID to receive upcalls. */ - OVS_USERSPACE_ATTR_USERDATA, /* u64 optional user-specified cookie. */ - __OVS_USERSPACE_ATTR_MAX -}; - -#define OVS_USERSPACE_ATTR_MAX (__OVS_USERSPACE_ATTR_MAX - 1) - -/** - * struct ovs_action_push_vlan - %OVS_ACTION_ATTR_PUSH_VLAN action argument. - * @vlan_tpid: Tag protocol identifier (TPID) to push. - * @vlan_tci: Tag control identifier (TCI) to push. The CFI bit must be set - * (but it will not be set in the 802.1Q header that is pushed). - * - * The @vlan_tpid value is typically %ETH_P_8021Q. The only acceptable TPID - * values are those that the kernel module also parses as 802.1Q headers, to - * prevent %OVS_ACTION_ATTR_PUSH_VLAN followed by %OVS_ACTION_ATTR_POP_VLAN - * from having surprising results. - */ -struct ovs_action_push_vlan { - __be16 vlan_tpid; /* 802.1Q TPID. */ - __be16 vlan_tci; /* 802.1Q TCI (VLAN ID and priority). */ -}; - -/** - * enum ovs_action_attr - Action types. - * - * @OVS_ACTION_ATTR_OUTPUT: Output packet to port. - * @OVS_ACTION_ATTR_USERSPACE: Send packet to userspace according to nested - * %OVS_USERSPACE_ATTR_* attributes. - * @OVS_ACTION_ATTR_SET: Replaces the contents of an existing header. The - * single nested %OVS_KEY_ATTR_* attribute specifies a header to modify and its - * value. - * @OVS_ACTION_ATTR_PUSH_VLAN: Push a new outermost 802.1Q header onto the - * packet. - * @OVS_ACTION_ATTR_POP_VLAN: Pop the outermost 802.1Q header off the packet. - * @OVS_ACTION_ATTR_SAMPLE: Probabilitically executes actions, as specified in - * the nested %OVS_SAMPLE_ATTR_* attributes. - * - * Only a single header can be set with a single %OVS_ACTION_ATTR_SET. Not all - * fields within a header are modifiable, e.g. the IPv4 protocol and fragment - * type may not be changed. - */ - -enum ovs_action_attr { - OVS_ACTION_ATTR_UNSPEC, - OVS_ACTION_ATTR_OUTPUT, /* u32 port number. */ - OVS_ACTION_ATTR_USERSPACE, /* Nested OVS_USERSPACE_ATTR_*. */ - OVS_ACTION_ATTR_SET, /* One nested OVS_KEY_ATTR_*. */ - OVS_ACTION_ATTR_PUSH_VLAN, /* struct ovs_action_push_vlan. */ - OVS_ACTION_ATTR_POP_VLAN, /* No argument. */ - OVS_ACTION_ATTR_SAMPLE, /* Nested OVS_SAMPLE_ATTR_*. */ - __OVS_ACTION_ATTR_MAX -}; - -#define OVS_ACTION_ATTR_MAX (__OVS_ACTION_ATTR_MAX - 1) +#include <uapi/linux/openvswitch.h> #endif /* _LINUX_OPENVSWITCH_H */ diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h index a4c562453f6b..b2a0f15f11fe 100644 --- a/include/linux/oprofile.h +++ b/include/linux/oprofile.h @@ -42,7 +42,6 @@ #define IBS_FETCH_CODE 13 #define IBS_OP_CODE 14 -struct super_block; struct dentry; struct file_operations; struct pt_regs; @@ -51,7 +50,7 @@ struct pt_regs; struct oprofile_operations { /* create any necessary configuration files in the oprofile fs. * Optional. */ - int (*create_files)(struct super_block * sb, struct dentry * root); + int (*create_files)(struct dentry * root); /* Do any necessary interrupt setup. Optional. */ int (*setup)(void); /* Do any necessary interrupt shutdown. Optional. */ @@ -125,27 +124,26 @@ void oprofile_add_trace(unsigned long eip); * Create a file of the given name as a child of the given root, with * the specified file operations. */ -int oprofilefs_create_file(struct super_block * sb, struct dentry * root, +int oprofilefs_create_file(struct dentry * root, char const * name, const struct file_operations * fops); -int oprofilefs_create_file_perm(struct super_block * sb, struct dentry * root, +int oprofilefs_create_file_perm(struct dentry * root, char const * name, const struct file_operations * fops, int perm); /** Create a file for read/write access to an unsigned long. */ -int oprofilefs_create_ulong(struct super_block * sb, struct dentry * root, +int oprofilefs_create_ulong(struct dentry * root, char const * name, ulong * val); /** Create a file for read-only access to an unsigned long. */ -int oprofilefs_create_ro_ulong(struct super_block * sb, struct dentry * root, +int oprofilefs_create_ro_ulong(struct dentry * root, char const * name, ulong * val); /** Create a file for read-only access to an atomic_t. */ -int oprofilefs_create_ro_atomic(struct super_block * sb, struct dentry * root, +int oprofilefs_create_ro_atomic(struct dentry * root, char const * name, atomic_t * val); /** create a directory */ -struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root, - char const * name); +struct dentry *oprofilefs_mkdir(struct dentry *parent, char const *name); /** * Write the given asciz string to the given user buffer @buf, updating *offset diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h index be655e4a2a75..2ee8cd2466b5 100644 --- a/include/linux/pageblock-flags.h +++ b/include/linux/pageblock-flags.h @@ -80,10 +80,4 @@ void set_pageblock_flags_group(struct page *page, unsigned long flags, PB_migrate_skip) #endif /* CONFIG_COMPACTION */ -#define get_pageblock_flags(page) \ - get_pageblock_flags_group(page, 0, PB_migrate_end) -#define set_pageblock_flags(page, flags) \ - set_pageblock_flags_group(page, flags, \ - 0, PB_migrate_end) - #endif /* PAGEBLOCK_FLAGS_H */ diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 0e38e13eb249..e3dea75a078b 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -149,7 +149,7 @@ static inline int page_cache_get_speculative(struct page *page) { VM_BUG_ON(in_interrupt()); -#if !defined(CONFIG_SMP) && defined(CONFIG_TREE_RCU) +#ifdef CONFIG_TINY_RCU # ifdef CONFIG_PREEMPT_COUNT VM_BUG_ON(!in_atomic()); # endif diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h index 2aa12b8499c0..e4dbfab37729 100644 --- a/include/linux/pagevec.h +++ b/include/linux/pagevec.h @@ -21,7 +21,7 @@ struct pagevec { }; void __pagevec_release(struct pagevec *pvec); -void __pagevec_lru_add(struct pagevec *pvec, enum lru_list lru); +void __pagevec_lru_add(struct pagevec *pvec); unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, pgoff_t start, unsigned nr_pages); unsigned pagevec_lookup_tag(struct pagevec *pvec, @@ -64,36 +64,4 @@ static inline void pagevec_release(struct pagevec *pvec) __pagevec_release(pvec); } -static inline void __pagevec_lru_add_anon(struct pagevec *pvec) -{ - __pagevec_lru_add(pvec, LRU_INACTIVE_ANON); -} - -static inline void __pagevec_lru_add_active_anon(struct pagevec *pvec) -{ - __pagevec_lru_add(pvec, LRU_ACTIVE_ANON); -} - -static inline void __pagevec_lru_add_file(struct pagevec *pvec) -{ - __pagevec_lru_add(pvec, LRU_INACTIVE_FILE); -} - -static inline void __pagevec_lru_add_active_file(struct pagevec *pvec) -{ - __pagevec_lru_add(pvec, LRU_ACTIVE_FILE); -} - -static inline void pagevec_lru_add_file(struct pagevec *pvec) -{ - if (pagevec_count(pvec)) - __pagevec_lru_add_file(pvec); -} - -static inline void pagevec_lru_add_anon(struct pagevec *pvec) -{ - if (pagevec_count(pvec)) - __pagevec_lru_add_anon(pvec); -} - #endif /* _LINUX_PAGEVEC_H */ diff --git a/include/linux/pata_arasan_cf_data.h b/include/linux/pata_arasan_cf_data.h index a7b4fc386e63..3cc21c9cc1e8 100644 --- a/include/linux/pata_arasan_cf_data.h +++ b/include/linux/pata_arasan_cf_data.h @@ -37,8 +37,6 @@ struct arasan_cf_pdata { #define CF_BROKEN_PIO (1) #define CF_BROKEN_MWDMA (1 << 1) #define CF_BROKEN_UDMA (1 << 2) - /* This is platform specific data for the DMA controller */ - void *dma_priv; }; static inline void diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 9a22b5efb384..d006f0ca60f4 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -41,8 +41,37 @@ static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus) return DEVICE_ACPI_HANDLE(dev); } + +void acpi_pci_add_bus(struct pci_bus *bus); +void acpi_pci_remove_bus(struct pci_bus *bus); + +#ifdef CONFIG_ACPI_PCI_SLOT +void acpi_pci_slot_init(void); +void acpi_pci_slot_enumerate(struct pci_bus *bus); +void acpi_pci_slot_remove(struct pci_bus *bus); +#else +static inline void acpi_pci_slot_init(void) { } +static inline void acpi_pci_slot_enumerate(struct pci_bus *bus) { } +static inline void acpi_pci_slot_remove(struct pci_bus *bus) { } #endif +#ifdef CONFIG_HOTPLUG_PCI_ACPI +void acpiphp_init(void); +void acpiphp_enumerate_slots(struct pci_bus *bus); +void acpiphp_remove_slots(struct pci_bus *bus); +void acpiphp_check_host_bridge(acpi_handle handle); +#else +static inline void acpiphp_init(void) { } +static inline void acpiphp_enumerate_slots(struct pci_bus *bus) { } +static inline void acpiphp_remove_slots(struct pci_bus *bus) { } +static inline void acpiphp_check_host_bridge(acpi_handle handle) { } +#endif + +#else /* CONFIG_ACPI */ +static inline void acpi_pci_add_bus(struct pci_bus *bus) { } +static inline void acpi_pci_remove_bus(struct pci_bus *bus) { } +#endif /* CONFIG_ACPI */ + #ifdef CONFIG_ACPI_APEI extern bool aer_acpi_firmware_first(void); #else diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h index c8320144fe79..8af4610c2e41 100644 --- a/include/linux/pci-aspm.h +++ b/include/linux/pci-aspm.h @@ -23,14 +23,14 @@ #define PCIE_LINK_STATE_CLKPM 4 #ifdef CONFIG_PCIEASPM -extern void pcie_aspm_init_link_state(struct pci_dev *pdev); -extern void pcie_aspm_exit_link_state(struct pci_dev *pdev); -extern void pcie_aspm_pm_state_change(struct pci_dev *pdev); -extern void pcie_aspm_powersave_config_link(struct pci_dev *pdev); -extern void pci_disable_link_state(struct pci_dev *pdev, int state); -extern void pci_disable_link_state_locked(struct pci_dev *pdev, int state); -extern void pcie_clear_aspm(struct pci_bus *bus); -extern void pcie_no_aspm(void); +void pcie_aspm_init_link_state(struct pci_dev *pdev); +void pcie_aspm_exit_link_state(struct pci_dev *pdev); +void pcie_aspm_pm_state_change(struct pci_dev *pdev); +void pcie_aspm_powersave_config_link(struct pci_dev *pdev); +void pci_disable_link_state(struct pci_dev *pdev, int state); +void pci_disable_link_state_locked(struct pci_dev *pdev, int state); +void pcie_clear_aspm(struct pci_bus *bus); +void pcie_no_aspm(void); #else static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { @@ -56,8 +56,8 @@ static inline void pcie_no_aspm(void) #endif #ifdef CONFIG_PCIEASPM_DEBUG /* this depends on CONFIG_PCIEASPM */ -extern void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev); -extern void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev); +void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev); +void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev); #else static inline void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) { diff --git a/include/linux/pci-ats.h b/include/linux/pci-ats.h index 7ef68724f0f0..68bcefd7fca0 100644 --- a/include/linux/pci-ats.h +++ b/include/linux/pci-ats.h @@ -14,9 +14,9 @@ struct pci_ats { #ifdef CONFIG_PCI_ATS -extern int pci_enable_ats(struct pci_dev *dev, int ps); -extern void pci_disable_ats(struct pci_dev *dev); -extern int pci_ats_queue_depth(struct pci_dev *dev); +int pci_enable_ats(struct pci_dev *dev, int ps); +void pci_disable_ats(struct pci_dev *dev); +int pci_ats_queue_depth(struct pci_dev *dev); /** * pci_ats_enabled - query the ATS status @@ -54,12 +54,12 @@ static inline int pci_ats_enabled(struct pci_dev *dev) #ifdef CONFIG_PCI_PRI -extern int pci_enable_pri(struct pci_dev *pdev, u32 reqs); -extern void pci_disable_pri(struct pci_dev *pdev); -extern bool pci_pri_enabled(struct pci_dev *pdev); -extern int pci_reset_pri(struct pci_dev *pdev); -extern bool pci_pri_stopped(struct pci_dev *pdev); -extern int pci_pri_status(struct pci_dev *pdev); +int pci_enable_pri(struct pci_dev *pdev, u32 reqs); +void pci_disable_pri(struct pci_dev *pdev); +bool pci_pri_enabled(struct pci_dev *pdev); +int pci_reset_pri(struct pci_dev *pdev); +bool pci_pri_stopped(struct pci_dev *pdev); +int pci_pri_status(struct pci_dev *pdev); #else /* CONFIG_PCI_PRI */ @@ -95,10 +95,10 @@ static inline int pci_pri_status(struct pci_dev *pdev) #ifdef CONFIG_PCI_PASID -extern int pci_enable_pasid(struct pci_dev *pdev, int features); -extern void pci_disable_pasid(struct pci_dev *pdev); -extern int pci_pasid_features(struct pci_dev *pdev); -extern int pci_max_pasids(struct pci_dev *pdev); +int pci_enable_pasid(struct pci_dev *pdev, int features); +void pci_disable_pasid(struct pci_dev *pdev); +int pci_pasid_features(struct pci_dev *pdev); +int pci_max_pasids(struct pci_dev *pdev); #else /* CONFIG_PCI_PASID */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 2461033a7987..da172f956ad6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -35,6 +35,21 @@ /* Include the ID list */ #include <linux/pci_ids.h> +/* + * The PCI interface treats multi-function devices as independent + * devices. The slot/function address of each device is encoded + * in a single byte as follows: + * + * 7:3 = slot + * 2:0 = function + * PCI_DEVFN(), PCI_SLOT(), and PCI_FUNC() are defined uapi/linux/pci.h + * In the interest of not exposing interfaces to user-space unnecessarily, + * the following kernel only defines are being added here. + */ +#define PCI_DEVID(bus, devfn) ((((u16)bus) << 8) | devfn) +/* return bus from PCI devid = ((u16)bus_number) << 8) | devfn */ +#define PCI_BUS_NUM(x) (((x) >> 8) & 0xff) + /* pci_slot represents a physical slot */ struct pci_slot { struct pci_bus *bus; /* The bus this slot is on */ @@ -168,6 +183,19 @@ enum pci_bus_flags { PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2, }; +/* These values come from the PCI Express Spec */ +enum pcie_link_width { + PCIE_LNK_WIDTH_RESRV = 0x00, + PCIE_LNK_X1 = 0x01, + PCIE_LNK_X2 = 0x02, + PCIE_LNK_X4 = 0x04, + PCIE_LNK_X8 = 0x08, + PCIE_LNK_X12 = 0x0C, + PCIE_LNK_X16 = 0x10, + PCIE_LNK_X32 = 0x20, + PCIE_LNK_WIDTH_UNKNOWN = 0xFF, +}; + /* Based on the PCI Hotplug Spec, but some values are made up by us */ enum pci_bus_speed { PCI_SPEED_33MHz = 0x00, @@ -232,6 +260,8 @@ struct pci_dev { u8 revision; /* PCI revision, low byte of class word */ u8 hdr_type; /* PCI header type (`multi' flag masked out) */ u8 pcie_cap; /* PCI-E capability offset */ + u8 msi_cap; /* MSI capability offset */ + u8 msix_cap; /* MSI-X capability offset */ u8 pcie_mpss:3; /* PCI-E Max Payload Size Supported */ u8 rom_base_reg; /* which config register controls the ROM */ u8 pin; /* which interrupt pin this device uses */ @@ -249,8 +279,7 @@ struct pci_dev { pci_power_t current_state; /* Current operating state. In ACPI-speak, this is D0-D3, D0 being fully functional, and D3 being off. */ - int pm_cap; /* PM capability offset in the - configuration space */ + u8 pm_cap; /* PM capability offset */ unsigned int pme_support:5; /* Bitmask of states from which PME# can be generated */ unsigned int pme_interrupt:1; @@ -348,7 +377,8 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev) return dev; } -extern struct pci_dev *alloc_pci_dev(void); +struct pci_dev *pci_alloc_dev(struct pci_bus *bus); +struct pci_dev * __deprecated alloc_pci_dev(void); #define to_pci_dev(n) container_of(n, struct pci_dev, dev) #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) @@ -416,6 +446,7 @@ struct pci_bus { struct resource busn_res; /* bus numbers routed to this bus */ struct pci_ops *ops; /* configuration access functions */ + struct msi_chip *msi; /* MSI controller */ void *sysdata; /* hook for sys-specific extension */ struct proc_dir_entry *procdir; /* directory entry in /proc/bus/pci */ @@ -504,10 +535,10 @@ struct pci_ops { * ACPI needs to be able to access PCI config space before we've done a * PCI bus scan and created pci_bus structures. */ -extern int raw_pci_read(unsigned int domain, unsigned int bus, - unsigned int devfn, int reg, int len, u32 *val); -extern int raw_pci_write(unsigned int domain, unsigned int bus, - unsigned int devfn, int reg, int len, u32 val); +int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, + int reg, int len, u32 *val); +int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn, + int reg, int len, u32 val); struct pci_bus_region { resource_size_t start; @@ -658,7 +689,7 @@ struct pci_driver { /* these external functions are only available when PCI support is enabled */ #ifdef CONFIG_PCI -extern void pcie_bus_configure_settings(struct pci_bus *bus, u8 smpss); +void pcie_bus_configure_settings(struct pci_bus *bus); enum pcie_bus_config_types { PCIE_BUS_TUNE_OFF, @@ -675,9 +706,11 @@ extern struct bus_type pci_bus_type; * code, or pci core code. */ extern struct list_head pci_root_buses; /* list of all known PCI buses */ /* Some device drivers need know if pci is initiated */ -extern int no_pci_devices(void); +int no_pci_devices(void); void pcibios_resource_survey_bus(struct pci_bus *bus); +void pcibios_add_bus(struct pci_bus *bus); +void pcibios_remove_bus(struct pci_bus *bus); void pcibios_fixup_bus(struct pci_bus *); int __must_check pcibios_enable_device(struct pci_dev *, int mask); /* Architecture specific versions may override this (weak) */ @@ -699,7 +732,7 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, struct pci_bus_region *region); void pcibios_scan_specific_bus(int busn); -extern struct pci_bus *pci_find_bus(int domain, int busnr); +struct pci_bus *pci_find_bus(int domain, int busnr); void pci_bus_add_devices(const struct pci_bus *bus); struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); @@ -732,14 +765,14 @@ struct resource *pci_find_parent_resource(const struct pci_dev *dev, u8 pci_swizzle_interrupt_pin(const struct pci_dev *dev, u8 pin); int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp); -extern struct pci_dev *pci_dev_get(struct pci_dev *dev); -extern void pci_dev_put(struct pci_dev *dev); -extern void pci_remove_bus(struct pci_bus *b); -extern void pci_stop_and_remove_bus_device(struct pci_dev *dev); +struct pci_dev *pci_dev_get(struct pci_dev *dev); +void pci_dev_put(struct pci_dev *dev); +void pci_remove_bus(struct pci_bus *b); +void pci_stop_and_remove_bus_device(struct pci_dev *dev); void pci_stop_root_bus(struct pci_bus *bus); void pci_remove_root_bus(struct pci_bus *bus); void pci_setup_cardbus(struct pci_bus *bus); -extern void pci_sort_breadthfirst(void); +void pci_sort_breadthfirst(void); #define dev_is_pci(d) ((d)->bus == &pci_bus_type) #define dev_is_pf(d) ((dev_is_pci(d) ? to_pci_dev(d)->is_physfn : false)) #define dev_num_vf(d) ((dev_is_pci(d) ? pci_num_vf(to_pci_dev(d)) : 0)) @@ -895,6 +928,7 @@ bool pci_check_and_unmask_intx(struct pci_dev *dev); void pci_msi_off(struct pci_dev *dev); int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size); int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask); +int pci_wait_for_pending_transaction(struct pci_dev *dev); int pcix_get_max_mmrbc(struct pci_dev *dev); int pcix_get_mmrbc(struct pci_dev *dev); int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc); @@ -902,9 +936,16 @@ int pcie_get_readrq(struct pci_dev *dev); int pcie_set_readrq(struct pci_dev *dev, int rq); int pcie_get_mps(struct pci_dev *dev); int pcie_set_mps(struct pci_dev *dev, int mps); +int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed, + enum pcie_link_width *width); int __pci_reset_function(struct pci_dev *dev); int __pci_reset_function_locked(struct pci_dev *dev); int pci_reset_function(struct pci_dev *dev); +int pci_probe_reset_slot(struct pci_slot *slot); +int pci_reset_slot(struct pci_slot *slot); +int pci_probe_reset_bus(struct pci_bus *bus); +int pci_reset_bus(struct pci_bus *bus); +void pci_reset_bridge_secondary_bus(struct pci_dev *dev); void pci_update_resource(struct pci_dev *dev, int resno); int __must_check pci_assign_resource(struct pci_dev *dev, int i); int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align); @@ -916,6 +957,7 @@ void pci_disable_rom(struct pci_dev *pdev); void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); +void __iomem __must_check *pci_platform_rom(struct pci_dev *pdev, size_t *size); /* Power management related routines */ int pci_save_state(struct pci_dev *dev); @@ -983,6 +1025,7 @@ int pci_claim_resource(struct pci_dev *, int); void pci_assign_unassigned_resources(void); void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge); void pci_assign_unassigned_bus_resources(struct pci_bus *bus); +void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus); void pdev_enable_device(struct pci_dev *); int pci_enable_resources(struct pci_dev *, int mask); void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), @@ -999,6 +1042,8 @@ int pci_request_selected_regions_exclusive(struct pci_dev *, int, const char *); void pci_release_selected_regions(struct pci_dev *, int); /* drivers/pci/bus.c */ +struct pci_bus *pci_bus_get(struct pci_bus *bus); +void pci_bus_put(struct pci_bus *bus); void pci_add_resource(struct list_head *resources, struct resource *res); void pci_add_resource_offset(struct list_head *resources, struct resource *res, resource_size_t offset); @@ -1021,7 +1066,6 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus, resource_size_t, resource_size_t), void *alignf_data); -void pci_enable_bridges(struct pci_bus *bus); /* Proper probing supporting hot-pluggable devices */ int __must_check __pci_register_driver(struct pci_driver *, struct module *, @@ -1141,18 +1185,17 @@ static inline int pci_msi_enabled(void) return 0; } #else -extern int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); -extern int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec); -extern void pci_msi_shutdown(struct pci_dev *dev); -extern void pci_disable_msi(struct pci_dev *dev); -extern int pci_msix_table_size(struct pci_dev *dev); -extern int pci_enable_msix(struct pci_dev *dev, - struct msix_entry *entries, int nvec); -extern void pci_msix_shutdown(struct pci_dev *dev); -extern void pci_disable_msix(struct pci_dev *dev); -extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); -extern void pci_restore_msi_state(struct pci_dev *dev); -extern int pci_msi_enabled(void); +int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); +int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec); +void pci_msi_shutdown(struct pci_dev *dev); +void pci_disable_msi(struct pci_dev *dev); +int pci_msix_table_size(struct pci_dev *dev); +int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); +void pci_msix_shutdown(struct pci_dev *dev); +void pci_disable_msix(struct pci_dev *dev); +void msi_remove_pci_irq_vectors(struct pci_dev *dev); +void pci_restore_msi_state(struct pci_dev *dev); +int pci_msi_enabled(void); #endif #ifdef CONFIG_PCIEPORTBUS @@ -1167,8 +1210,8 @@ extern bool pcie_ports_auto; static inline int pcie_aspm_enabled(void) { return 0; } static inline bool pcie_aspm_support_enabled(void) { return false; } #else -extern int pcie_aspm_enabled(void); -extern bool pcie_aspm_support_enabled(void); +int pcie_aspm_enabled(void); +bool pcie_aspm_support_enabled(void); #endif #ifdef CONFIG_PCIEAER @@ -1186,8 +1229,8 @@ static inline void pcie_set_ecrc_checking(struct pci_dev *dev) } static inline void pcie_ecrc_get_policy(char *str) {}; #else -extern void pcie_set_ecrc_checking(struct pci_dev *dev); -extern void pcie_ecrc_get_policy(char *str); +void pcie_set_ecrc_checking(struct pci_dev *dev); +void pcie_ecrc_get_policy(char *str); #endif #define pci_enable_msi(pdev) pci_enable_msi_block(pdev, 1) @@ -1198,9 +1241,9 @@ int ht_create_irq(struct pci_dev *dev, int idx); void ht_destroy_irq(unsigned int irq); #endif /* CONFIG_HT_IRQ */ -extern void pci_cfg_access_lock(struct pci_dev *dev); -extern bool pci_cfg_access_trylock(struct pci_dev *dev); -extern void pci_cfg_access_unlock(struct pci_dev *dev); +void pci_cfg_access_lock(struct pci_dev *dev); +bool pci_cfg_access_trylock(struct pci_dev *dev); +void pci_cfg_access_unlock(struct pci_dev *dev); /* * PCI domain support. Sometimes called PCI segment (eg by ACPI), @@ -1225,7 +1268,7 @@ static inline int pci_proc_domain(struct pci_bus *bus) /* some architectures require additional setup to direct VGA traffic */ typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode, unsigned int command_bits, u32 flags); -extern void pci_register_set_vga_state(arch_set_vga_state_t func); +void pci_register_set_vga_state(arch_set_vga_state_t func); #else /* CONFIG_PCI is not enabled */ @@ -1625,10 +1668,15 @@ void pcibios_set_master(struct pci_dev *dev); int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state); int pcibios_add_device(struct pci_dev *dev); +void pcibios_release_device(struct pci_dev *dev); + +#ifdef CONFIG_HIBERNATE_CALLBACKS +extern struct dev_pm_ops pcibios_pm_ops; +#endif #ifdef CONFIG_PCI_MMCONFIG -extern void __init pci_mmcfg_early_init(void); -extern void __init pci_mmcfg_late_init(void); +void __init pci_mmcfg_early_init(void); +void __init pci_mmcfg_late_init(void); #else static inline void pci_mmcfg_early_init(void) { } static inline void pci_mmcfg_late_init(void) { } @@ -1639,12 +1687,13 @@ int pci_ext_cfg_avail(void); void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar); #ifdef CONFIG_PCI_IOV -extern int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); -extern void pci_disable_sriov(struct pci_dev *dev); -extern irqreturn_t pci_sriov_migration(struct pci_dev *dev); -extern int pci_num_vf(struct pci_dev *dev); -extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); -extern int pci_sriov_get_totalvfs(struct pci_dev *dev); +int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); +void pci_disable_sriov(struct pci_dev *dev); +irqreturn_t pci_sriov_migration(struct pci_dev *dev); +int pci_num_vf(struct pci_dev *dev); +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); #else static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) { @@ -1661,6 +1710,10 @@ static inline int pci_num_vf(struct pci_dev *dev) { return 0; } +static inline int pci_vfs_assigned(struct pci_dev *dev) +{ + return 0; +} static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs) { return 0; @@ -1672,8 +1725,8 @@ static inline int pci_sriov_get_totalvfs(struct pci_dev *dev) #endif #if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE) -extern void pci_hp_create_module_link(struct pci_slot *pci_slot); -extern void pci_hp_remove_module_link(struct pci_slot *pci_slot); +void pci_hp_create_module_link(struct pci_slot *pci_slot); +void pci_hp_remove_module_link(struct pci_slot *pci_slot); #endif /** @@ -1817,13 +1870,13 @@ int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off, /* PCI <-> OF binding helpers */ #ifdef CONFIG_OF struct device_node; -extern void pci_set_of_node(struct pci_dev *dev); -extern void pci_release_of_node(struct pci_dev *dev); -extern void pci_set_bus_of_node(struct pci_bus *bus); -extern void pci_release_bus_of_node(struct pci_bus *bus); +void pci_set_of_node(struct pci_dev *dev); +void pci_release_of_node(struct pci_dev *dev); +void pci_set_bus_of_node(struct pci_bus *bus); +void pci_release_bus_of_node(struct pci_bus *bus); /* Arch may override this (weak) */ -extern struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus); +struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus); static inline struct device_node * pci_device_to_OF_node(const struct pci_dev *pdev) diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index 45fc162cbdc0..430dd963707b 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -28,19 +28,6 @@ #ifndef _PCI_HOTPLUG_H #define _PCI_HOTPLUG_H -/* These values come from the PCI Express Spec */ -enum pcie_link_width { - PCIE_LNK_WIDTH_RESRV = 0x00, - PCIE_LNK_X1 = 0x01, - PCIE_LNK_X2 = 0x02, - PCIE_LNK_X4 = 0x04, - PCIE_LNK_X8 = 0x08, - PCIE_LNK_X12 = 0x0C, - PCIE_LNK_X16 = 0x10, - PCIE_LNK_X32 = 0x20, - PCIE_LNK_WIDTH_UNKNOWN = 0xFF, -}; - /** * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use * @owner: The module owner of this structure @@ -63,6 +50,9 @@ enum pcie_link_width { * @get_adapter_status: Called to get see if an adapter is present in the slot or not. * If this field is NULL, the value passed in the struct hotplug_slot_info * will be used when this value is requested by a user. + * @reset_slot: Optional interface to allow override of a bus reset for the + * slot for cases where a secondary bus reset can result in spurious + * hotplug events or where a slot can be reset independent of the bus. * * The table of function pointers that is passed to the hotplug pci core by a * hotplug pci driver. These functions are called by the hotplug pci core when @@ -80,6 +70,7 @@ struct hotplug_slot_ops { int (*get_attention_status) (struct hotplug_slot *slot, u8 *value); int (*get_latch_status) (struct hotplug_slot *slot, u8 *value); int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value); + int (*reset_slot) (struct hotplug_slot *slot, int probe); }; /** @@ -125,12 +116,12 @@ static inline const char *hotplug_slot_name(const struct hotplug_slot *slot) return pci_slot_name(slot->pci_slot); } -extern int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *pbus, - int nr, const char *name, - struct module *owner, const char *mod_name); -extern int pci_hp_deregister(struct hotplug_slot *slot); -extern int __must_check pci_hp_change_slot_info (struct hotplug_slot *slot, - struct hotplug_slot_info *info); +int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *pbus, int nr, + const char *name, struct module *owner, + const char *mod_name); +int pci_hp_deregister(struct hotplug_slot *slot); +int __must_check pci_hp_change_slot_info(struct hotplug_slot *slot, + struct hotplug_slot_info *info); /* use a define to avoid include chaining to get THIS_MODULE & friends */ #define pci_hp_register(slot, pbus, devnr, name) \ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f11c1c2609d5..97fbecdd7a40 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -518,12 +518,16 @@ #define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303 #define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304 #define PCI_DEVICE_ID_AMD_15H_M10H_F3 0x1403 +#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F3 0x141d +#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F4 0x141e #define PCI_DEVICE_ID_AMD_15H_NB_F0 0x1600 #define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601 #define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602 #define PCI_DEVICE_ID_AMD_15H_NB_F3 0x1603 #define PCI_DEVICE_ID_AMD_15H_NB_F4 0x1604 #define PCI_DEVICE_ID_AMD_15H_NB_F5 0x1605 +#define PCI_DEVICE_ID_AMD_16H_NB_F3 0x1533 +#define PCI_DEVICE_ID_AMD_16H_NB_F4 0x1534 #define PCI_DEVICE_ID_AMD_CNB17H_F3 0x1703 #define PCI_DEVICE_ID_AMD_LANCE 0x2000 #define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 @@ -554,7 +558,6 @@ #define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450 #define PCI_DEVICE_ID_AMD_8131_APIC 0x7451 #define PCI_DEVICE_ID_AMD_8132_BRIDGE 0x7458 -#define PCI_DEVICE_ID_AMD_HUDSON2_SMBUS 0x780b #define PCI_DEVICE_ID_AMD_CS5535_IDE 0x208F #define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090 #define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091 @@ -566,8 +569,9 @@ #define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A #define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081 #define PCI_DEVICE_ID_AMD_LX_AES 0x2082 -#define PCI_DEVICE_ID_AMD_HUDSON2_IDE 0x780c #define PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE 0x7800 +#define PCI_DEVICE_ID_AMD_HUDSON2_SMBUS 0x780b +#define PCI_DEVICE_ID_AMD_HUDSON2_IDE 0x780c #define PCI_VENDOR_ID_TRIDENT 0x1023 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000 @@ -754,6 +758,7 @@ #define PCI_DEVICE_ID_HP_CISSE 0x323a #define PCI_DEVICE_ID_HP_CISSF 0x323b #define PCI_DEVICE_ID_HP_CISSH 0x323c +#define PCI_DEVICE_ID_HP_CISSI 0x3239 #define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031 #define PCI_VENDOR_ID_PCTECH 0x1042 @@ -1309,6 +1314,8 @@ #define PCI_DEVICE_ID_IMS_TT128 0x9128 #define PCI_DEVICE_ID_IMS_TT3D 0x9135 +#define PCI_VENDOR_ID_AMCC 0x10e8 + #define PCI_VENDOR_ID_INTERG 0x10ea #define PCI_DEVICE_ID_INTERG_1682 0x1682 #define PCI_DEVICE_ID_INTERG_2000 0x2000 @@ -1604,6 +1611,7 @@ #define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334 #define PCI_VENDOR_ID_MARVELL 0x11ab +#define PCI_VENDOR_ID_MARVELL_EXT 0x1b4b #define PCI_DEVICE_ID_MARVELL_GT64111 0x4146 #define PCI_DEVICE_ID_MARVELL_GT64260 0x6430 #define PCI_DEVICE_ID_MARVELL_MV64360 0x6460 @@ -2144,11 +2152,13 @@ #define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e #define PCI_DEVICE_ID_NX2_57712 0x1662 #define PCI_DEVICE_ID_NX2_57712E 0x1663 +#define PCI_DEVICE_ID_NX2_57712_MF 0x1663 #define PCI_DEVICE_ID_TIGON3_5714 0x1668 #define PCI_DEVICE_ID_TIGON3_5714S 0x1669 #define PCI_DEVICE_ID_TIGON3_5780 0x166a #define PCI_DEVICE_ID_TIGON3_5780S 0x166b #define PCI_DEVICE_ID_TIGON3_5705F 0x166e +#define PCI_DEVICE_ID_NX2_57712_VF 0x166f #define PCI_DEVICE_ID_TIGON3_5754M 0x1672 #define PCI_DEVICE_ID_TIGON3_5755M 0x1673 #define PCI_DEVICE_ID_TIGON3_5756 0x1674 @@ -2174,13 +2184,15 @@ #define PCI_DEVICE_ID_TIGON3_5787 0x169b #define PCI_DEVICE_ID_TIGON3_5788 0x169c #define PCI_DEVICE_ID_TIGON3_5789 0x169d +#define PCI_DEVICE_ID_NX2_57840_4_10 0x16a1 +#define PCI_DEVICE_ID_NX2_57840_2_20 0x16a2 +#define PCI_DEVICE_ID_NX2_57840_MF 0x16a4 #define PCI_DEVICE_ID_NX2_57800_MF 0x16a5 #define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 #define PCI_DEVICE_ID_TIGON3_5703X 0x16a7 #define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 #define PCI_DEVICE_ID_NX2_57800_VF 0x16a9 #define PCI_DEVICE_ID_NX2_5706S 0x16aa -#define PCI_DEVICE_ID_NX2_57840_MF 0x16a4 #define PCI_DEVICE_ID_NX2_5708S 0x16ac #define PCI_DEVICE_ID_NX2_57840_VF 0x16ad #define PCI_DEVICE_ID_NX2_57810_MF 0x16ae @@ -2249,12 +2261,10 @@ /* * ADDI-DATA GmbH communication cards <info@addi-data.com> */ -#define PCI_VENDOR_ID_ADDIDATA_OLD 0x10E8 #define PCI_VENDOR_ID_ADDIDATA 0x15B8 #define PCI_DEVICE_ID_ADDIDATA_APCI7500 0x7000 #define PCI_DEVICE_ID_ADDIDATA_APCI7420 0x7001 #define PCI_DEVICE_ID_ADDIDATA_APCI7300 0x7002 -#define PCI_DEVICE_ID_ADDIDATA_APCI7800 0x818E #define PCI_DEVICE_ID_ADDIDATA_APCI7500_2 0x7009 #define PCI_DEVICE_ID_ADDIDATA_APCI7420_2 0x700A #define PCI_DEVICE_ID_ADDIDATA_APCI7300_2 0x700B @@ -2469,6 +2479,9 @@ #define PCI_VENDOR_ID_ASMEDIA 0x1b21 +#define PCI_VENDOR_ID_CIRCUITCO 0x1cc8 +#define PCI_SUBSYSTEM_ID_CIRCUITCO_MINNOWBOARD 0x0001 + #define PCI_VENDOR_ID_TEKRAM 0x1de1 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 diff --git a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h index e6f91b1406d8..9572669eea97 100644 --- a/include/linux/pcieport_if.h +++ b/include/linux/pcieport_if.h @@ -62,7 +62,7 @@ struct pcie_port_service_driver { #define to_service_driver(d) \ container_of(d, struct pcie_port_service_driver, driver) -extern int pcie_port_service_register(struct pcie_port_service_driver *new); -extern void pcie_port_service_unregister(struct pcie_port_service_driver *new); +int pcie_port_service_register(struct pcie_port_service_driver *new); +void pcie_port_service_unregister(struct pcie_port_service_driver *new); #endif /* _PCIEPORT_IF_H_ */ diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h index 27ef6b190ea6..57e890abe1f0 100644 --- a/include/linux/percpu-defs.h +++ b/include/linux/percpu-defs.h @@ -22,9 +22,12 @@ * Macro which verifies @ptr is a percpu pointer without evaluating * @ptr. This is to be used in percpu accessors to verify that the * input parameter is a percpu pointer. + * + * + 0 is required in order to convert the pointer type from a + * potential array type to a pointer to a single item of the array. */ #define __verify_pcpu_ptr(ptr) do { \ - const void __percpu *__vpp_verify = (typeof(ptr))NULL; \ + const void __percpu *__vpp_verify = (typeof((ptr) + 0))NULL; \ (void)__vpp_verify; \ } while (0) diff --git a/include/linux/percpu-refcount.h b/include/linux/percpu-refcount.h new file mode 100644 index 000000000000..95961f0bf62d --- /dev/null +++ b/include/linux/percpu-refcount.h @@ -0,0 +1,174 @@ +/* + * Percpu refcounts: + * (C) 2012 Google, Inc. + * Author: Kent Overstreet <koverstreet@google.com> + * + * This implements a refcount with similar semantics to atomic_t - atomic_inc(), + * atomic_dec_and_test() - but percpu. + * + * There's one important difference between percpu refs and normal atomic_t + * refcounts; you have to keep track of your initial refcount, and then when you + * start shutting down you call percpu_ref_kill() _before_ dropping the initial + * refcount. + * + * The refcount will have a range of 0 to ((1U << 31) - 1), i.e. one bit less + * than an atomic_t - this is because of the way shutdown works, see + * percpu_ref_kill()/PCPU_COUNT_BIAS. + * + * Before you call percpu_ref_kill(), percpu_ref_put() does not check for the + * refcount hitting 0 - it can't, if it was in percpu mode. percpu_ref_kill() + * puts the ref back in single atomic_t mode, collecting the per cpu refs and + * issuing the appropriate barriers, and then marks the ref as shutting down so + * that percpu_ref_put() will check for the ref hitting 0. After it returns, + * it's safe to drop the initial ref. + * + * USAGE: + * + * See fs/aio.c for some example usage; it's used there for struct kioctx, which + * is created when userspaces calls io_setup(), and destroyed when userspace + * calls io_destroy() or the process exits. + * + * In the aio code, kill_ioctx() is called when we wish to destroy a kioctx; it + * calls percpu_ref_kill(), then hlist_del_rcu() and sychronize_rcu() to remove + * the kioctx from the proccess's list of kioctxs - after that, there can't be + * any new users of the kioctx (from lookup_ioctx()) and it's then safe to drop + * the initial ref with percpu_ref_put(). + * + * Code that does a two stage shutdown like this often needs some kind of + * explicit synchronization to ensure the initial refcount can only be dropped + * once - percpu_ref_kill() does this for you, it returns true once and false if + * someone else already called it. The aio code uses it this way, but it's not + * necessary if the code has some other mechanism to synchronize teardown. + * around. + */ + +#ifndef _LINUX_PERCPU_REFCOUNT_H +#define _LINUX_PERCPU_REFCOUNT_H + +#include <linux/atomic.h> +#include <linux/kernel.h> +#include <linux/percpu.h> +#include <linux/rcupdate.h> + +struct percpu_ref; +typedef void (percpu_ref_func_t)(struct percpu_ref *); + +struct percpu_ref { + atomic_t count; + /* + * The low bit of the pointer indicates whether the ref is in percpu + * mode; if set, then get/put will manipulate the atomic_t (this is a + * hack because we need to keep the pointer around for + * percpu_ref_kill_rcu()) + */ + unsigned __percpu *pcpu_count; + percpu_ref_func_t *release; + percpu_ref_func_t *confirm_kill; + struct rcu_head rcu; +}; + +int __must_check percpu_ref_init(struct percpu_ref *ref, + percpu_ref_func_t *release); +void percpu_ref_cancel_init(struct percpu_ref *ref); +void percpu_ref_kill_and_confirm(struct percpu_ref *ref, + percpu_ref_func_t *confirm_kill); + +/** + * percpu_ref_kill - drop the initial ref + * @ref: percpu_ref to kill + * + * Must be used to drop the initial ref on a percpu refcount; must be called + * precisely once before shutdown. + * + * Puts @ref in non percpu mode, then does a call_rcu() before gathering up the + * percpu counters and dropping the initial ref. + */ +static inline void percpu_ref_kill(struct percpu_ref *ref) +{ + return percpu_ref_kill_and_confirm(ref, NULL); +} + +#define PCPU_STATUS_BITS 2 +#define PCPU_STATUS_MASK ((1 << PCPU_STATUS_BITS) - 1) +#define PCPU_REF_PTR 0 +#define PCPU_REF_DEAD 1 + +#define REF_STATUS(count) (((unsigned long) count) & PCPU_STATUS_MASK) + +/** + * percpu_ref_get - increment a percpu refcount + * @ref: percpu_ref to get + * + * Analagous to atomic_inc(). + */ +static inline void percpu_ref_get(struct percpu_ref *ref) +{ + unsigned __percpu *pcpu_count; + + rcu_read_lock_sched(); + + pcpu_count = ACCESS_ONCE(ref->pcpu_count); + + if (likely(REF_STATUS(pcpu_count) == PCPU_REF_PTR)) + __this_cpu_inc(*pcpu_count); + else + atomic_inc(&ref->count); + + rcu_read_unlock_sched(); +} + +/** + * percpu_ref_tryget - try to increment a percpu refcount + * @ref: percpu_ref to try-get + * + * Increment a percpu refcount unless it has already been killed. Returns + * %true on success; %false on failure. + * + * Completion of percpu_ref_kill() in itself doesn't guarantee that tryget + * will fail. For such guarantee, percpu_ref_kill_and_confirm() should be + * used. After the confirm_kill callback is invoked, it's guaranteed that + * no new reference will be given out by percpu_ref_tryget(). + */ +static inline bool percpu_ref_tryget(struct percpu_ref *ref) +{ + unsigned __percpu *pcpu_count; + int ret = false; + + rcu_read_lock_sched(); + + pcpu_count = ACCESS_ONCE(ref->pcpu_count); + + if (likely(REF_STATUS(pcpu_count) == PCPU_REF_PTR)) { + __this_cpu_inc(*pcpu_count); + ret = true; + } + + rcu_read_unlock_sched(); + + return ret; +} + +/** + * percpu_ref_put - decrement a percpu refcount + * @ref: percpu_ref to put + * + * Decrement the refcount, and if 0, call the release function (which was passed + * to percpu_ref_init()) + */ +static inline void percpu_ref_put(struct percpu_ref *ref) +{ + unsigned __percpu *pcpu_count; + + rcu_read_lock_sched(); + + pcpu_count = ACCESS_ONCE(ref->pcpu_count); + + if (likely(REF_STATUS(pcpu_count) == PCPU_REF_PTR)) + __this_cpu_dec(*pcpu_count); + else if (unlikely(atomic_dec_and_test(&ref->count))) + ref->release(ref); + + rcu_read_unlock_sched(); +} + +#endif diff --git a/include/linux/percpu_ida.h b/include/linux/percpu_ida.h new file mode 100644 index 000000000000..0b23edbee309 --- /dev/null +++ b/include/linux/percpu_ida.h @@ -0,0 +1,60 @@ +#ifndef __PERCPU_IDA_H__ +#define __PERCPU_IDA_H__ + +#include <linux/types.h> +#include <linux/bitops.h> +#include <linux/init.h> +#include <linux/spinlock_types.h> +#include <linux/wait.h> +#include <linux/cpumask.h> + +struct percpu_ida_cpu; + +struct percpu_ida { + /* + * number of tags available to be allocated, as passed to + * percpu_ida_init() + */ + unsigned nr_tags; + + struct percpu_ida_cpu __percpu *tag_cpu; + + /* + * Bitmap of cpus that (may) have tags on their percpu freelists: + * steal_tags() uses this to decide when to steal tags, and which cpus + * to try stealing from. + * + * It's ok for a freelist to be empty when its bit is set - steal_tags() + * will just keep looking - but the bitmap _must_ be set whenever a + * percpu freelist does have tags. + */ + cpumask_t cpus_have_tags; + + struct { + spinlock_t lock; + /* + * When we go to steal tags from another cpu (see steal_tags()), + * we want to pick a cpu at random. Cycling through them every + * time we steal is a bit easier and more or less equivalent: + */ + unsigned cpu_last_stolen; + + /* For sleeping on allocation failure */ + wait_queue_head_t wait; + + /* + * Global freelist - it's a stack where nr_free points to the + * top + */ + unsigned nr_free; + unsigned *freelist; + } ____cacheline_aligned_in_smp; +}; + +int percpu_ida_alloc(struct percpu_ida *pool, gfp_t gfp); +void percpu_ida_free(struct percpu_ida *pool, unsigned tag); + +void percpu_ida_destroy(struct percpu_ida *pool); +int percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags); + +#endif /* __PERCPU_IDA_H__ */ diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index e47ee462c2f2..866e85c5eb94 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -21,7 +21,6 @@ */ #ifdef CONFIG_PERF_EVENTS -# include <linux/cgroup.h> # include <asm/perf_event.h> # include <asm/local64.h> #endif @@ -49,6 +48,7 @@ struct perf_guest_info_callbacks { #include <linux/cpu.h> #include <linux/irq_work.h> #include <linux/static_key.h> +#include <linux/jump_label_ratelimit.h> #include <linux/atomic.h> #include <linux/sysfs.h> #include <linux/perf_regs.h> @@ -65,25 +65,6 @@ struct perf_raw_record { }; /* - * single taken branch record layout: - * - * from: source instruction (may not always be a branch insn) - * to: branch target - * mispred: branch target was mispredicted - * predicted: branch target was predicted - * - * support for mispred, predicted is optional. In case it - * is not supported mispred = predicted = 0. - */ -struct perf_branch_entry { - __u64 from; - __u64 to; - __u64 mispred:1, /* target mispredicted */ - predicted:1,/* target predicted */ - reserved:62; -}; - -/* * branch stack layout: * nr: number of taken branches stored in entries[] * @@ -114,6 +95,8 @@ struct hw_perf_event_extra { int idx; /* index in shared_regs->regs[] */ }; +struct event_constraint; + /** * struct hw_perf_event - performance event hardware details: */ @@ -128,9 +111,12 @@ struct hw_perf_event { int event_base_rdpmc; int idx; int last_cpu; + int flags; struct hw_perf_event_extra extra_reg; struct hw_perf_event_extra branch_reg; + + struct event_constraint *constraint; }; struct { /* software */ struct hrtimer hrtimer; @@ -188,12 +174,13 @@ struct pmu { struct device *dev; const struct attribute_group **attr_groups; - char *name; + const char *name; int type; int * __percpu pmu_disable_count; struct perf_cpu_context * __percpu pmu_cpu_context; int task_ctx_nr; + int hrtimer_interval_ms; /* * Fully disable/enable this PMU, can be used to protect from the PMI @@ -299,22 +286,7 @@ struct swevent_hlist { #define PERF_ATTACH_GROUP 0x02 #define PERF_ATTACH_TASK 0x04 -#ifdef CONFIG_CGROUP_PERF -/* - * perf_cgroup_info keeps track of time_enabled for a cgroup. - * This is a per-cpu dynamically allocated data structure. - */ -struct perf_cgroup_info { - u64 time; - u64 timestamp; -}; - -struct perf_cgroup { - struct cgroup_subsys_state css; - struct perf_cgroup_info *info; /* timing info, one per cpu */ -}; -#endif - +struct perf_cgroup; struct ring_buffer; /** @@ -404,8 +376,7 @@ struct perf_event { /* mmap bits */ struct mutex mmap_mutex; atomic_t mmap_count; - int mmap_locked; - struct user_struct *mmap_user; + struct ring_buffer *rb; struct list_head rb_entry; @@ -516,8 +487,9 @@ struct perf_cpu_context { struct perf_event_context *task_ctx; int active_oncpu; int exclusive; + struct hrtimer hrtimer; + ktime_t hrtimer_interval; struct list_head rotation_list; - int jiffies_interval; struct pmu *unique_pmu; struct perf_cgroup *cgrp; }; @@ -533,7 +505,7 @@ struct perf_output_handle { #ifdef CONFIG_PERF_EVENTS -extern int perf_pmu_register(struct pmu *pmu, char *name, int type); +extern int perf_pmu_register(struct pmu *pmu, const char *name, int type); extern void perf_pmu_unregister(struct pmu *pmu); extern int perf_num_counters(void); @@ -583,11 +555,13 @@ struct perf_sample_data { u32 reserved; } cpu_entry; u64 period; + union perf_mem_data_src data_src; struct perf_callchain_entry *callchain; struct perf_raw_record *raw; struct perf_branch_stack *br_stack; struct perf_regs_user regs_user; u64 stack_user_size; + u64 weight; }; static inline void perf_sample_data_init(struct perf_sample_data *data, @@ -601,6 +575,8 @@ static inline void perf_sample_data_init(struct perf_sample_data *data, data->regs_user.abi = PERF_SAMPLE_REGS_ABI_NONE; data->regs_user.regs = NULL; data->stack_user_size = 0; + data->weight = 0; + data->data_src.val = 0; } extern void perf_output_sample(struct perf_output_handle *handle, @@ -707,10 +683,17 @@ static inline void perf_callchain_store(struct perf_callchain_entry *entry, u64 extern int sysctl_perf_event_paranoid; extern int sysctl_perf_event_mlock; extern int sysctl_perf_event_sample_rate; +extern int sysctl_perf_cpu_time_max_percent; + +extern void perf_sample_event_took(u64 sample_len_ns); extern int perf_proc_update_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); +extern int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos); + static inline bool perf_paranoid_tracepoint_raw(void) { @@ -754,6 +737,7 @@ extern unsigned int perf_output_skip(struct perf_output_handle *handle, unsigned int len); extern int perf_swevent_get_recursion_context(void); extern void perf_swevent_put_recursion_context(int rctx); +extern u64 perf_swevent_set_period(struct perf_event *event); extern void perf_event_enable(struct perf_event *event); extern void perf_event_disable(struct perf_event *event); extern int __perf_event_disable(void *info); @@ -793,20 +777,33 @@ static inline void perf_event_fork(struct task_struct *tsk) { } static inline void perf_event_init(void) { } static inline int perf_swevent_get_recursion_context(void) { return -1; } static inline void perf_swevent_put_recursion_context(int rctx) { } +static inline u64 perf_swevent_set_period(struct perf_event *event) { return 0; } static inline void perf_event_enable(struct perf_event *event) { } static inline void perf_event_disable(struct perf_event *event) { } static inline int __perf_event_disable(void *info) { return -1; } static inline void perf_event_task_tick(void) { } #endif +#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_NO_HZ_FULL) +extern bool perf_event_can_stop_tick(void); +#else +static inline bool perf_event_can_stop_tick(void) { return true; } +#endif + +#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL) +extern void perf_restore_debug_store(void); +#else +static inline void perf_restore_debug_store(void) { } +#endif + #define perf_output_put(handle, x) perf_output_copy((handle), &(x), sizeof(x)) /* - * This has to have a higher priority than migration_notifier in sched.c. + * This has to have a higher priority than migration_notifier in sched/core.c. */ #define perf_cpu_notifier(fn) \ do { \ - static struct notifier_block fn##_nb __cpuinitdata = \ + static struct notifier_block fn##_nb = \ { .notifier_call = fn, .priority = CPU_PRI_PERF }; \ unsigned long cpu = smp_processor_id(); \ unsigned long flags; \ @@ -825,6 +822,7 @@ do { \ struct perf_pmu_events_attr { struct device_attribute attr; u64 id; + const char *event_str; }; #define PMU_EVENT_ATTR(_name, _var, _id, _show) \ diff --git a/include/linux/phy.h b/include/linux/phy.h index 33999adbf8c8..64ab823f7b74 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -49,6 +49,7 @@ #define PHY_HAS_INTERRUPT 0x00000001 #define PHY_HAS_MAGICANEG 0x00000002 +#define PHY_IS_INTERNAL 0x00000004 /* Interface Mode definitions */ typedef enum { @@ -57,6 +58,7 @@ typedef enum { PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_SGMII, PHY_INTERFACE_MODE_TBI, + PHY_INTERFACE_MODE_REVMII, PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII, PHY_INTERFACE_MODE_RGMII_ID, @@ -261,6 +263,7 @@ struct phy_c45_device_ids { * phy_id: UID for this device found during discovery * c45_ids: 802.3-c45 Device Identifers if is_c45. * is_c45: Set to true if this phy uses clause 45 addressing. + * is_internal: Set to true if this phy is internal to a MAC. * state: state of the PHY for management purposes * dev_flags: Device-specific flags used by the PHY driver. * addr: Bus address of PHY @@ -298,6 +301,7 @@ struct phy_device { struct phy_c45_device_ids c45_ids; bool is_c45; + bool is_internal; enum phy_state state; @@ -455,6 +459,14 @@ struct phy_driver { */ void (*txtstamp)(struct phy_device *dev, struct sk_buff *skb, int type); + /* Some devices (e.g. qnap TS-119P II) require PHY register changes to + * enable Wake on LAN, so set_wol is provided to be called in the + * ethernet driver's set_wol function. */ + int (*set_wol)(struct phy_device *dev, struct ethtool_wolinfo *wol); + + /* See set_wol, but for checking whether Wake on LAN is enabled. */ + void (*get_wol)(struct phy_device *dev, struct ethtool_wolinfo *wol); + struct device_driver driver; }; #define to_phy_driver(d) container_of(d, struct phy_driver, driver) @@ -500,6 +512,27 @@ static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val) return mdiobus_write(phydev->bus, phydev->addr, regnum, val); } +/** + * phy_interrupt_is_valid - Convenience function for testing a given PHY irq + * @phydev: the phy_device struct + * + * NOTE: must be kept in sync with addition/removal of PHY_POLL and + * PHY_IGNORE_INTERRUPT + */ +static inline bool phy_interrupt_is_valid(struct phy_device *phydev) +{ + return phydev->irq != PHY_POLL && phydev->irq != PHY_IGNORE_INTERRUPT; +} + +/** + * phy_is_internal - Convenience function for testing if a PHY is internal + * @phydev: the phy_device struct + */ +static inline bool phy_is_internal(struct phy_device *phydev) +{ + return phydev->is_internal; +} + struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, bool is_c45, struct phy_c45_device_ids *c45_ids); struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45); @@ -537,6 +570,8 @@ void phy_drivers_unregister(struct phy_driver *drv, int n); int phy_driver_register(struct phy_driver *new_driver); int phy_drivers_register(struct phy_driver *new_driver, int n); void phy_state_machine(struct work_struct *work); +void phy_change(struct work_struct *work); +void phy_mac_interrupt(struct phy_device *phydev, int new_link); void phy_start_machine(struct phy_device *phydev, void (*handler)(struct net_device *)); void phy_stop_machine(struct phy_device *phydev); @@ -560,6 +595,8 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable); int phy_get_eee_err(struct phy_device *phydev); int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data); int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data); +int phy_ethtool_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol); +void phy_ethtool_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol); int __init mdio_bus_init(void); void mdio_bus_exit(void); diff --git a/include/linux/pid.h b/include/linux/pid.h index a089a3c447fc..23705a53abba 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h @@ -86,11 +86,9 @@ extern struct task_struct *get_pid_task(struct pid *pid, enum pid_type); extern struct pid *get_task_pid(struct task_struct *task, enum pid_type type); /* - * attach_pid() and detach_pid() must be called with the tasklist_lock - * write-held. + * these helpers must be called with the tasklist_lock write-held. */ -extern void attach_pid(struct task_struct *task, enum pid_type type, - struct pid *pid); +extern void attach_pid(struct task_struct *task, enum pid_type); extern void detach_pid(struct task_struct *task, enum pid_type); extern void change_pid(struct task_struct *task, enum pid_type, struct pid *pid); diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h index 215e5e3dda10..e2772666f004 100644 --- a/include/linux/pid_namespace.h +++ b/include/linux/pid_namespace.h @@ -4,6 +4,7 @@ #include <linux/sched.h> #include <linux/bug.h> #include <linux/mm.h> +#include <linux/workqueue.h> #include <linux/threads.h> #include <linux/nsproxy.h> #include <linux/kref.h> @@ -13,7 +14,9 @@ struct pidmap { void *page; }; -#define PIDMAP_ENTRIES ((PID_MAX_LIMIT + 8*PAGE_SIZE - 1)/PAGE_SIZE/8) +#define BITS_PER_PAGE (PAGE_SIZE * 8) +#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) +#define PIDMAP_ENTRIES ((PID_MAX_LIMIT+BITS_PER_PAGE-1)/BITS_PER_PAGE) struct bsd_acct_struct; @@ -28,6 +31,7 @@ struct pid_namespace { struct pid_namespace *parent; #ifdef CONFIG_PROC_FS struct vfsmount *proc_mnt; + struct dentry *proc_self; #endif #ifdef CONFIG_BSD_PROCESS_ACCT struct bsd_acct_struct *bacct; diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 4aad3cea69ae..18eccefea06e 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -40,6 +40,25 @@ extern int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s); extern struct pinctrl * __must_check devm_pinctrl_get(struct device *dev); extern void devm_pinctrl_put(struct pinctrl *p); +#ifdef CONFIG_PM +extern int pinctrl_pm_select_default_state(struct device *dev); +extern int pinctrl_pm_select_sleep_state(struct device *dev); +extern int pinctrl_pm_select_idle_state(struct device *dev); +#else +static inline int pinctrl_pm_select_default_state(struct device *dev) +{ + return 0; +} +static inline int pinctrl_pm_select_sleep_state(struct device *dev) +{ + return 0; +} +static inline int pinctrl_pm_select_idle_state(struct device *dev) +{ + return 0; +} +#endif + #else /* !CONFIG_PINCTRL */ static inline int pinctrl_request_gpio(unsigned gpio) @@ -92,6 +111,21 @@ static inline void devm_pinctrl_put(struct pinctrl *p) { } +static inline int pinctrl_pm_select_default_state(struct device *dev) +{ + return 0; +} + +static inline int pinctrl_pm_select_sleep_state(struct device *dev) +{ + return 0; +} + +static inline int pinctrl_pm_select_idle_state(struct device *dev) +{ + return 0; +} + #endif /* CONFIG_PINCTRL */ static inline struct pinctrl * __must_check pinctrl_get_select( @@ -158,47 +192,4 @@ static inline struct pinctrl * __must_check devm_pinctrl_get_select_default( return devm_pinctrl_get_select(dev, PINCTRL_STATE_DEFAULT); } -#ifdef CONFIG_PINCONF - -extern int pin_config_get(const char *dev_name, const char *name, - unsigned long *config); -extern int pin_config_set(const char *dev_name, const char *name, - unsigned long config); -extern int pin_config_group_get(const char *dev_name, - const char *pin_group, - unsigned long *config); -extern int pin_config_group_set(const char *dev_name, - const char *pin_group, - unsigned long config); - -#else - -static inline int pin_config_get(const char *dev_name, const char *name, - unsigned long *config) -{ - return 0; -} - -static inline int pin_config_set(const char *dev_name, const char *name, - unsigned long config) -{ - return 0; -} - -static inline int pin_config_group_get(const char *dev_name, - const char *pin_group, - unsigned long *config) -{ - return 0; -} - -static inline int pin_config_group_set(const char *dev_name, - const char *pin_group, - unsigned long config) -{ - return 0; -} - -#endif - #endif /* __LINUX_PINCTRL_CONSUMER_H */ diff --git a/include/linux/pinctrl/devinfo.h b/include/linux/pinctrl/devinfo.h index 6e5f8a985ea7..281cb91ddcf5 100644 --- a/include/linux/pinctrl/devinfo.h +++ b/include/linux/pinctrl/devinfo.h @@ -28,6 +28,10 @@ struct dev_pin_info { struct pinctrl *p; struct pinctrl_state *default_state; +#ifdef CONFIG_PM + struct pinctrl_state *sleep_state; + struct pinctrl_state *idle_state; +#endif }; extern int pinctrl_bind_pins(struct device *dev); diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h index 72474e18f1e0..fb90ef5eb038 100644 --- a/include/linux/pinctrl/pinconf-generic.h +++ b/include/linux/pinctrl/pinconf-generic.h @@ -29,25 +29,38 @@ * if for example some other pin is going to drive the signal connected * to it for a while. Pins used for input are usually always high * impedance. + * @PIN_CONFIG_BIAS_BUS_HOLD: the pin will be set to weakly latch so that it + * weakly drives the last value on a tristate bus, also known as a "bus + * holder", "bus keeper" or "repeater". This allows another device on the + * bus to change the value by driving the bus high or low and switching to + * tristate. The argument is ignored. * @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high * impedance to VDD). If the argument is != 0 pull-up is enabled, - * if it is 0, pull-up is disabled. + * if it is 0, pull-up is total, i.e. the pin is connected to VDD. * @PIN_CONFIG_BIAS_PULL_DOWN: the pin will be pulled down (usually with high * impedance to GROUND). If the argument is != 0 pull-down is enabled, - * if it is 0, pull-down is disabled. + * if it is 0, pull-down is total, i.e. the pin is connected to GROUND. + * @PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: the pin will be pulled up or down based + * on embedded knowledge of the controller hardware, like current mux + * function. The pull direction and possibly strength too will normally + * be decided completely inside the hardware block and not be readable + * from the kernel side. + * If the argument is != 0 pull up/down is enabled, if it is 0, the + * configuration is ignored. The proper way to disable it is to use + * @PIN_CONFIG_BIAS_DISABLE. * @PIN_CONFIG_DRIVE_PUSH_PULL: the pin will be driven actively high and * low, this is the most typical case and is typically achieved with two - * active transistors on the output. Sending this config will enabale + * active transistors on the output. Setting this config will enable * push-pull mode, the argument is ignored. * @PIN_CONFIG_DRIVE_OPEN_DRAIN: the pin will be driven with open drain (open * collector) which means it is usually wired with other output ports - * which are then pulled up with an external resistor. Sending this - * config will enabale open drain mode, the argument is ignored. + * which are then pulled up with an external resistor. Setting this + * config will enable open drain mode, the argument is ignored. * @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source - * (open emitter). Sending this config will enabale open drain mode, the + * (open emitter). Setting this config will enable open drain mode, the * argument is ignored. - * @PIN_CONFIG_DRIVE_STRENGTH: the pin will output the current passed as - * argument. The argument is in mA. + * @PIN_CONFIG_DRIVE_STRENGTH: the pin will sink or source at most the current + * passed as argument. The argument is in mA. * @PIN_CONFIG_INPUT_SCHMITT_ENABLE: control schmitt-trigger mode on the pin. * If the argument != 0, schmitt-trigger mode is enabled. If it's 0, * schmitt-trigger mode is disabled. @@ -57,14 +70,14 @@ * setting pins to this mode. * @PIN_CONFIG_INPUT_DEBOUNCE: this will configure the pin to debounce mode, * which means it will wait for signals to settle when reading inputs. The - * argument gives the debounce time on a custom format. Setting the + * argument gives the debounce time in usecs. Setting the * argument to zero turns debouncing off. * @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power * supplies, the argument to this parameter (on a custom format) tells * the driver which alternative power source to use. * @PIN_CONFIG_SLEW_RATE: if the pin can select slew rate, the argument to - * this parameter (on a custom format) tells the driver which alternative - * slew rate to use. + * this parameter (on a custom format) tells the driver which alternative + * slew rate to use. * @PIN_CONFIG_LOW_POWER_MODE: this will configure the pin for low power * operation, if several modes of operation are supported these can be * passed in the argument on a custom form, else just use argument 1 @@ -78,8 +91,10 @@ enum pin_config_param { PIN_CONFIG_BIAS_DISABLE, PIN_CONFIG_BIAS_HIGH_IMPEDANCE, + PIN_CONFIG_BIAS_BUS_HOLD, PIN_CONFIG_BIAS_PULL_UP, PIN_CONFIG_BIAS_PULL_DOWN, + PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, PIN_CONFIG_DRIVE_PUSH_PULL, PIN_CONFIG_DRIVE_OPEN_DRAIN, PIN_CONFIG_DRIVE_OPEN_SOURCE, @@ -122,6 +137,39 @@ static inline unsigned long pinconf_to_config_packed(enum pin_config_param param return PIN_CONF_PACKED(param, argument); } +#ifdef CONFIG_OF + +#include <linux/device.h> +#include <linux/pinctrl/machine.h> +struct pinctrl_dev; +struct pinctrl_map; + +int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, struct pinctrl_map **map, + unsigned *reserved_maps, unsigned *num_maps, + enum pinctrl_map_type type); +int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np_config, struct pinctrl_map **map, + unsigned *num_maps, enum pinctrl_map_type type); + +static inline int pinconf_generic_dt_node_to_map_group( + struct pinctrl_dev *pctldev, struct device_node *np_config, + struct pinctrl_map **map, unsigned *num_maps) +{ + return pinconf_generic_dt_node_to_map(pctldev, np_config, map, num_maps, + PIN_MAP_TYPE_CONFIGS_GROUP); +} + +static inline int pinconf_generic_dt_node_to_map_pin( + struct pinctrl_dev *pctldev, struct device_node *np_config, + struct pinctrl_map **map, unsigned *num_maps) +{ + return pinconf_generic_dt_node_to_map(pctldev, np_config, map, num_maps, + PIN_MAP_TYPE_CONFIGS_PIN); +} + +#endif + #endif /* CONFIG_GENERIC_PINCONF */ #endif /* __LINUX_PINCTRL_PINCONF_GENERIC_H */ diff --git a/include/linux/pinctrl/pinconf.h b/include/linux/pinctrl/pinconf.h index e7a720104a47..09eb80f2574a 100644 --- a/include/linux/pinctrl/pinconf.h +++ b/include/linux/pinctrl/pinconf.h @@ -14,6 +14,8 @@ #ifdef CONFIG_PINCONF +#include <linux/pinctrl/machine.h> + struct pinctrl_dev; struct seq_file; @@ -28,6 +30,7 @@ struct seq_file; * @pin_config_set: configure an individual pin * @pin_config_group_get: get configurations for an entire pin group * @pin_config_group_set: configure all pins in a group + * @pin_config_dbg_parse_modify: optional debugfs to modify a pin configuration * @pin_config_dbg_show: optional debugfs display hook that will provide * per-device info for a certain pin in debugfs * @pin_config_group_dbg_show: optional debugfs display hook that will provide @@ -44,13 +47,18 @@ struct pinconf_ops { unsigned long *config); int (*pin_config_set) (struct pinctrl_dev *pctldev, unsigned pin, - unsigned long config); + unsigned long *configs, + unsigned num_configs); int (*pin_config_group_get) (struct pinctrl_dev *pctldev, unsigned selector, unsigned long *config); int (*pin_config_group_set) (struct pinctrl_dev *pctldev, unsigned selector, - unsigned long config); + unsigned long *configs, + unsigned num_configs); + int (*pin_config_dbg_parse_modify) (struct pinctrl_dev *pctldev, + const char *arg, + unsigned long *config); void (*pin_config_dbg_show) (struct pinctrl_dev *pctldev, struct seq_file *s, unsigned offset); diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 778804df293f..5979147d2bda 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -49,7 +49,8 @@ struct pinctrl_pin_desc { * @name: a name for the chip in this range * @id: an ID number for the chip in this range * @base: base offset of the GPIO range - * @pin_base: base pin number of the GPIO range + * @pin_base: base pin number of the GPIO range if pins == NULL + * @pins: enumeration of pins in GPIO range or NULL * @npins: number of pins in the GPIO range, including the base number * @gc: an optional pointer to a gpio_chip */ @@ -59,6 +60,7 @@ struct pinctrl_gpio_range { unsigned int id; unsigned int base; unsigned int pin_base; + unsigned const *pins; unsigned int npins; struct gpio_chip *gc; }; @@ -118,9 +120,9 @@ struct pinctrl_desc { const char *name; struct pinctrl_pin_desc const *pins; unsigned int npins; - struct pinctrl_ops *pctlops; - struct pinmux_ops *pmxops; - struct pinconf_ops *confops; + const struct pinctrl_ops *pctlops; + const struct pinmux_ops *pmxops; + const struct pinconf_ops *confops; struct module *owner; }; diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index ad1a427b5267..b8809fef61f5 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -27,6 +27,7 @@ struct pipe_buffer { /** * struct pipe_inode_info - a linux kernel pipe + * @mutex: mutex protecting the whole thing * @wait: reader/writer wait point in case of empty/full pipe * @nrbufs: the number of non-empty pipe buffers in this pipe * @buffers: total number of buffers (should be a power of 2) @@ -34,26 +35,27 @@ struct pipe_buffer { * @tmp_page: cached released page * @readers: number of current readers of this pipe * @writers: number of current writers of this pipe + * @files: number of struct file refering this pipe (protected by ->i_lock) * @waiting_writers: number of writers blocked waiting for room * @r_counter: reader counter * @w_counter: writer counter * @fasync_readers: reader side fasync * @fasync_writers: writer side fasync - * @inode: inode this pipe is attached to * @bufs: the circular array of pipe buffers **/ struct pipe_inode_info { + struct mutex mutex; wait_queue_head_t wait; unsigned int nrbufs, curbuf, buffers; unsigned int readers; unsigned int writers; + unsigned int files; unsigned int waiting_writers; unsigned int r_counter; unsigned int w_counter; struct page *tmp_page; struct fasync_struct *fasync_readers; struct fasync_struct *fasync_writers; - struct inode *inode; struct pipe_buffer *bufs; }; @@ -144,9 +146,8 @@ int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *); /* Drop the inode semaphore and wait for a pipe event, atomically */ void pipe_wait(struct pipe_inode_info *pipe); -struct pipe_inode_info * alloc_pipe_info(struct inode * inode); -void free_pipe_info(struct inode * inode); -void __free_pipe_info(struct pipe_inode_info *); +struct pipe_inode_info *alloc_pipe_info(void); +void free_pipe_info(struct pipe_inode_info *); /* Generic pipe buffer ops functions */ void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int); diff --git a/include/linux/platform_data/ad7303.h b/include/linux/platform_data/ad7303.h new file mode 100644 index 000000000000..de6a7a6b4bbf --- /dev/null +++ b/include/linux/platform_data/ad7303.h @@ -0,0 +1,21 @@ +/* + * Analog Devices AD7303 DAC driver + * + * Copyright 2013 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef __IIO_ADC_AD7303_H__ +#define __IIO_ADC_AD7303_H__ + +/** + * struct ad7303_platform_data - AD7303 platform data + * @use_external_ref: If set to true use an external voltage reference connected + * to the REF pin, otherwise use the internal reference derived from Vdd. + */ +struct ad7303_platform_data { + bool use_external_ref; +}; + +#endif diff --git a/include/linux/platform_data/arm-ux500-pm.h b/include/linux/platform_data/arm-ux500-pm.h new file mode 100644 index 000000000000..8dff64b29ec0 --- /dev/null +++ b/include/linux/platform_data/arm-ux500-pm.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) ST-Ericsson SA 2010-2013 + * Author: Rickard Andersson <rickard.andersson@stericsson.com> for + * ST-Ericsson. + * Author: Daniel Lezcano <daniel.lezcano@linaro.org> for Linaro. + * License terms: GNU General Public License (GPL) version 2 + * + */ + +#ifndef ARM_UX500_PM_H +#define ARM_UX500_PM_H + +int prcmu_gic_decouple(void); +int prcmu_gic_recouple(void); +bool prcmu_gic_pending_irq(void); +bool prcmu_pending_irq(void); +bool prcmu_is_cpu_in_wfi(int cpu); +int prcmu_copy_gic_settings(void); +void ux500_pm_init(u32 phy_base, u32 size); + +#endif /* ARM_UX500_PM_H */ diff --git a/include/linux/platform_data/asoc-s3c.h b/include/linux/platform_data/asoc-s3c.h index 88272591a895..9efc04dd255a 100644 --- a/include/linux/platform_data/asoc-s3c.h +++ b/include/linux/platform_data/asoc-s3c.h @@ -36,6 +36,7 @@ struct samsung_i2s { */ #define QUIRK_NO_MUXPSR (1 << 2) #define QUIRK_NEED_RSTCLR (1 << 3) +#define QUIRK_SUPPORTS_TDM (1 << 4) /* Quirks of the I2S controller */ u32 quirks; dma_addr_t idma_addr; diff --git a/include/linux/platform_data/asoc-ux500-msp.h b/include/linux/platform_data/asoc-ux500-msp.h new file mode 100644 index 000000000000..9991aea3d577 --- /dev/null +++ b/include/linux/platform_data/asoc-ux500-msp.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson + * License terms: GNU General Public License (GPL), version 2. + */ + +#ifndef __MSP_H +#define __MSP_H + +#include <linux/platform_data/dma-ste-dma40.h> + +enum msp_i2s_id { + MSP_I2S_0 = 0, + MSP_I2S_1, + MSP_I2S_2, + MSP_I2S_3, +}; + +/* Platform data structure for a MSP I2S-device */ +struct msp_i2s_platform_data { + enum msp_i2s_id id; + struct stedma40_chan_cfg *msp_i2s_dma_rx; + struct stedma40_chan_cfg *msp_i2s_dma_tx; +}; + +#endif diff --git a/include/linux/platform_data/at91_adc.h b/include/linux/platform_data/at91_adc.h index e15745b4f3a5..b3ca1e94e0c8 100644 --- a/include/linux/platform_data/at91_adc.h +++ b/include/linux/platform_data/at91_adc.h @@ -14,12 +14,16 @@ (Interruptions registers mostly) * @status_register: Offset of the Interrupt Status Register * @trigger_register: Offset of the Trigger setup register + * @mr_prescal_mask: Mask of the PRESCAL field in the adc MR register + * @mr_startup_mask: Mask of the STARTUP field in the adc MR register */ struct at91_adc_reg_desc { u8 channel_base; u32 drdy_mask; u8 status_register; u8 trigger_register; + u32 mr_prescal_mask; + u32 mr_startup_mask; }; /** diff --git a/include/linux/platform_data/atmel-aes.h b/include/linux/platform_data/atmel-aes.h deleted file mode 100644 index ab68082fbcb0..000000000000 --- a/include/linux/platform_data/atmel-aes.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __LINUX_ATMEL_AES_H -#define __LINUX_ATMEL_AES_H - -#include <linux/platform_data/dma-atmel.h> - -/** - * struct aes_dma_data - DMA data for AES - */ -struct aes_dma_data { - struct at_dma_slave txdata; - struct at_dma_slave rxdata; -}; - -/** - * struct aes_platform_data - board-specific AES configuration - * @dma_slave: DMA slave interface to use in data transfers. - */ -struct aes_platform_data { - struct aes_dma_data *dma_slave; -}; - -#endif /* __LINUX_ATMEL_AES_H */ diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h index 6a293b7fff3b..cea9f70133c5 100644 --- a/include/linux/platform_data/atmel.h +++ b/include/linux/platform_data/atmel.h @@ -71,6 +71,10 @@ struct atmel_nand_data { u8 on_flash_bbt; /* bbt on flash */ struct mtd_partition *parts; unsigned int num_parts; + bool has_dma; /* support dma transfer */ + + /* default is false, only for at32ap7000 chip is true */ + bool need_reset_workaround; }; /* Serial */ diff --git a/include/linux/platform_data/bd6107.h b/include/linux/platform_data/bd6107.h new file mode 100644 index 000000000000..671d6502d241 --- /dev/null +++ b/include/linux/platform_data/bd6107.h @@ -0,0 +1,19 @@ +/* + * bd6107.h - Rohm BD6107 LEDs Driver + * + * 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 __BD6107_H__ +#define __BD6107_H__ + +struct device; + +struct bd6107_platform_data { + struct device *fbdev; + int reset; /* Reset GPIO */ + unsigned int def_value; +}; + +#endif diff --git a/include/linux/platform_data/brcmfmac-sdio.h b/include/linux/platform_data/brcmfmac-sdio.h new file mode 100644 index 000000000000..e75dcbf2b230 --- /dev/null +++ b/include/linux/platform_data/brcmfmac-sdio.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _LINUX_BRCMFMAC_PLATFORM_H +#define _LINUX_BRCMFMAC_PLATFORM_H + +/* + * Platform specific driver functions and data. Through the platform specific + * device data functions can be provided to help the brcmfmac driver to + * operate with the device in combination with the used platform. + * + * Use the platform data in the following (similar) way: + * + * +#include <brcmfmac_platform.h> + + +static void brcmfmac_power_on(void) +{ +} + +static void brcmfmac_power_off(void) +{ +} + +static void brcmfmac_reset(void) +{ +} + +static struct brcmfmac_sdio_platform_data brcmfmac_sdio_pdata = { + .power_on = brcmfmac_power_on, + .power_off = brcmfmac_power_off, + .reset = brcmfmac_reset +}; + +static struct platform_device brcmfmac_device = { + .name = BRCMFMAC_SDIO_PDATA_NAME, + .id = PLATFORM_DEVID_NONE, + .dev.platform_data = &brcmfmac_sdio_pdata +}; + +void __init brcmfmac_init_pdata(void) +{ + brcmfmac_sdio_pdata.oob_irq_supported = true; + brcmfmac_sdio_pdata.oob_irq_nr = gpio_to_irq(GPIO_BRCMF_SDIO_OOB); + brcmfmac_sdio_pdata.oob_irq_flags = IORESOURCE_IRQ | + IORESOURCE_IRQ_HIGHLEVEL; + platform_device_register(&brcmfmac_device); +} + * + * + * Note: the brcmfmac can be loaded as module or be statically built-in into + * the kernel. If built-in then do note that it uses module_init (and + * module_exit) routines which equal device_initcall. So if you intend to + * create a module with the platform specific data for the brcmfmac and have + * it built-in to the kernel then use a higher initcall then device_initcall + * (see init.h). If this is not done then brcmfmac will load without problems + * but will not pickup the platform data. + * + * When the driver does not "detect" platform driver data then it will continue + * without reporting anything and just assume there is no data needed. Which is + * probably true for most platforms. + * + * Explanation of the platform_data fields: + * + * drive_strength: is the preferred drive_strength to be used for the SDIO + * pins. If 0 then a default value will be used. This is the target drive + * strength, the exact drive strength which will be used depends on the + * capabilities of the device. + * + * oob_irq_supported: does the board have support for OOB interrupts. SDIO + * in-band interrupts are relatively slow and for having less overhead on + * interrupt processing an out of band interrupt can be used. If the HW + * supports this then enable this by setting this field to true and configure + * the oob related fields. + * + * oob_irq_nr, oob_irq_flags: the OOB interrupt information. The values are + * used for registering the irq using request_irq function. + * + * broken_sg_support: flag for broken sg list support of SDIO host controller. + * Set this to true if the SDIO host controller has higher align requirement + * than 32 bytes for each scatterlist item. + * + * sd_head_align: alignment requirement for start of data buffer + * + * sd_sgentry_align: length alignment requirement for each sg entry + * + * power_on: This function is called by the brcmfmac when the module gets + * loaded. This can be particularly useful for low power devices. The platform + * spcific routine may for example decide to power up the complete device. + * If there is no use-case for this function then provide NULL. + * + * power_off: This function is called by the brcmfmac when the module gets + * unloaded. At this point the device can be powered down or otherwise be reset. + * So if an actual power_off is not supported but reset is then reset the device + * when this function gets called. This can be particularly useful for low power + * devices. If there is no use-case for this function (either power-down or + * reset) then provide NULL. + * + * reset: This function can get called if the device communication broke down. + * This functionality is particularly useful in case of SDIO type devices. It is + * possible to reset a dongle via sdio data interface, but it requires that + * this is fully functional. This function is chip/module specific and this + * function should return only after the complete reset has completed. + */ + +#define BRCMFMAC_SDIO_PDATA_NAME "brcmfmac_sdio" + +struct brcmfmac_sdio_platform_data { + unsigned int drive_strength; + bool oob_irq_supported; + unsigned int oob_irq_nr; + unsigned long oob_irq_flags; + bool broken_sg_support; + unsigned short sd_head_align; + unsigned short sd_sgentry_align; + void (*power_on)(void); + void (*power_off)(void); + void (*reset)(void); +}; + +#endif /* _LINUX_BRCMFMAC_PLATFORM_H */ diff --git a/include/linux/platform_data/camera-mx3.h b/include/linux/platform_data/camera-mx3.h index f226ee3777e1..a910dadc8258 100644 --- a/include/linux/platform_data/camera-mx3.h +++ b/include/linux/platform_data/camera-mx3.h @@ -33,6 +33,8 @@ #define MX3_CAMERA_DATAWIDTH_MASK (MX3_CAMERA_DATAWIDTH_4 | MX3_CAMERA_DATAWIDTH_8 | \ MX3_CAMERA_DATAWIDTH_10 | MX3_CAMERA_DATAWIDTH_15) +struct v4l2_async_subdev; + /** * struct mx3_camera_pdata - i.MX3x camera platform data * @flags: MX3_CAMERA_* flags @@ -43,6 +45,8 @@ struct mx3_camera_pdata { unsigned long flags; unsigned long mclk_10khz; struct device *dma_dev; + struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */ + int *asd_sizes; /* 0-terminated array of asd group sizes */ }; #endif diff --git a/include/linux/platform_data/camera-rcar.h b/include/linux/platform_data/camera-rcar.h new file mode 100644 index 000000000000..dfc83c581593 --- /dev/null +++ b/include/linux/platform_data/camera-rcar.h @@ -0,0 +1,25 @@ +/* + * Platform data for Renesas R-Car VIN soc-camera driver + * + * Copyright (C) 2011-2013 Renesas Solutions Corp. + * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.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 __CAMERA_RCAR_H_ +#define __CAMERA_RCAR_H_ + +#define RCAR_VIN_HSYNC_ACTIVE_LOW (1 << 0) +#define RCAR_VIN_VSYNC_ACTIVE_LOW (1 << 1) +#define RCAR_VIN_BT601 (1 << 2) +#define RCAR_VIN_BT656 (1 << 3) + +struct rcar_vin_platform_data { + unsigned int flags; +}; + +#endif /* __CAMERA_RCAR_H_ */ diff --git a/include/linux/platform_data/clk-lpss.h b/include/linux/platform_data/clk-lpss.h new file mode 100644 index 000000000000..23901992b9dd --- /dev/null +++ b/include/linux/platform_data/clk-lpss.h @@ -0,0 +1,23 @@ +/* + * Intel Low Power Subsystem clocks. + * + * Copyright (C) 2013, Intel Corporation + * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> + * Rafael J. Wysocki <rafael.j.wysocki@intel.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 __CLK_LPSS_H +#define __CLK_LPSS_H + +struct lpss_clk_data { + const char *name; + struct clk *clk; +}; + +extern int lpt_clk_init(void); + +#endif /* __CLK_LPSS_H */ diff --git a/include/linux/platform_data/clk-ux500.h b/include/linux/platform_data/clk-ux500.h index 3af0da1f3be5..9d98f3aaa16c 100644 --- a/include/linux/platform_data/clk-ux500.h +++ b/include/linux/platform_data/clk-ux500.h @@ -10,8 +10,11 @@ #ifndef __CLK_UX500_H #define __CLK_UX500_H -void u8500_clk_init(void); -void u9540_clk_init(void); -void u8540_clk_init(void); +void u8500_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base, + u32 clkrst5_base, u32 clkrst6_base); +void u9540_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base, + u32 clkrst5_base, u32 clkrst6_base); +void u8540_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base, + u32 clkrst5_base, u32 clkrst6_base); #endif /* __CLK_UX500_H */ diff --git a/include/linux/platform_data/coda.h b/include/linux/platform_data/coda.h new file mode 100644 index 000000000000..6ad4410d9e20 --- /dev/null +++ b/include/linux/platform_data/coda.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2013 Philipp Zabel, Pengutronix + * + * 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 PLATFORM_CODA_H +#define PLATFORM_CODA_H + +struct device; + +struct coda_platform_data { + struct device *iram_dev; +}; + +#endif diff --git a/include/linux/platform_data/cpsw.h b/include/linux/platform_data/cpsw.h deleted file mode 100644 index 798fb80b024b..000000000000 --- a/include/linux/platform_data/cpsw.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Texas Instruments Ethernet Switch Driver - * - * Copyright (C) 2012 Texas Instruments - * - * 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 __CPSW_H__ -#define __CPSW_H__ - -#include <linux/if_ether.h> - -struct cpsw_slave_data { - char phy_id[MII_BUS_ID_SIZE]; - int phy_if; - u8 mac_addr[ETH_ALEN]; - u16 dual_emac_res_vlan; /* Reserved VLAN for DualEMAC */ - -}; - -struct cpsw_platform_data { - u32 ss_reg_ofs; /* Subsystem control register offset */ - u32 channels; /* number of cpdma channels (symmetric) */ - u32 slaves; /* number of slave cpgmac ports */ - struct cpsw_slave_data *slave_data; - u32 cpts_active_slave; /* time stamping slave */ - u32 cpts_clock_mult; /* convert input clock ticks to nanoseconds */ - u32 cpts_clock_shift; /* convert input clock ticks to nanoseconds */ - u32 ale_entries; /* ale table size */ - u32 bd_ram_size; /*buffer descriptor ram size */ - u32 rx_descs; /* Number of Rx Descriptios */ - u32 mac_control; /* Mac control register */ - u16 default_vlan; /* Def VLAN for ALE lookup in VLAN aware mode*/ - bool dual_emac; /* Enable Dual EMAC mode */ -}; - -#endif /* __CPSW_H__ */ diff --git a/include/linux/platform_data/crypto-atmel.h b/include/linux/platform_data/crypto-atmel.h new file mode 100644 index 000000000000..b46e0d9062a0 --- /dev/null +++ b/include/linux/platform_data/crypto-atmel.h @@ -0,0 +1,22 @@ +#ifndef __LINUX_CRYPTO_ATMEL_H +#define __LINUX_CRYPTO_ATMEL_H + +#include <linux/platform_data/dma-atmel.h> + +/** + * struct crypto_dma_data - DMA data for AES/TDES/SHA + */ +struct crypto_dma_data { + struct at_dma_slave txdata; + struct at_dma_slave rxdata; +}; + +/** + * struct crypto_platform_data - board-specific AES/TDES/SHA configuration + * @dma_slave: DMA slave interface to use in data transfers. + */ +struct crypto_platform_data { + struct crypto_dma_data *dma_slave; +}; + +#endif /* __LINUX_CRYPTO_ATMEL_H */ diff --git a/include/linux/platform_data/cyttsp4.h b/include/linux/platform_data/cyttsp4.h new file mode 100644 index 000000000000..6eba54aff1dc --- /dev/null +++ b/include/linux/platform_data/cyttsp4.h @@ -0,0 +1,76 @@ +/* + * Header file for: + * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers. + * For use with Cypress Txx3xx parts. + * Supported parts include: + * CY8CTST341 + * CY8CTMA340 + * + * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. + * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.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, and only version 2, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contact Cypress Semiconductor at www.cypress.com (kev@cypress.com) + * + */ +#ifndef _CYTTSP4_H_ +#define _CYTTSP4_H_ + +#define CYTTSP4_MT_NAME "cyttsp4_mt" +#define CYTTSP4_I2C_NAME "cyttsp4_i2c_adapter" +#define CYTTSP4_SPI_NAME "cyttsp4_spi_adapter" + +#define CY_TOUCH_SETTINGS_MAX 32 + +struct touch_framework { + const uint16_t *abs; + uint8_t size; + uint8_t enable_vkeys; +} __packed; + +struct cyttsp4_mt_platform_data { + struct touch_framework *frmwrk; + unsigned short flags; + char const *inp_dev_name; +}; + +struct touch_settings { + const uint8_t *data; + uint32_t size; + uint8_t tag; +} __packed; + +struct cyttsp4_core_platform_data { + int irq_gpio; + int rst_gpio; + int level_irq_udelay; + int (*xres)(struct cyttsp4_core_platform_data *pdata, + struct device *dev); + int (*init)(struct cyttsp4_core_platform_data *pdata, + int on, struct device *dev); + int (*power)(struct cyttsp4_core_platform_data *pdata, + int on, struct device *dev, atomic_t *ignore_irq); + int (*irq_stat)(struct cyttsp4_core_platform_data *pdata, + struct device *dev); + struct touch_settings *sett[CY_TOUCH_SETTINGS_MAX]; +}; + +struct cyttsp4_platform_data { + struct cyttsp4_core_platform_data *core_pdata; + struct cyttsp4_mt_platform_data *mt_pdata; +}; + +#endif /* _CYTTSP4_H_ */ diff --git a/include/linux/platform_data/dma-atmel.h b/include/linux/platform_data/dma-atmel.h index cab0997be3de..e95f19c65873 100644 --- a/include/linux/platform_data/dma-atmel.h +++ b/include/linux/platform_data/dma-atmel.h @@ -35,16 +35,20 @@ struct at_dma_slave { /* Platform-configurable bits in CFG */ +#define ATC_PER_MSB(h) ((0x30U & (h)) >> 4) /* Extract most significant bits of a handshaking identifier */ + #define ATC_SRC_PER(h) (0xFU & (h)) /* Channel src rq associated with periph handshaking ifc h */ #define ATC_DST_PER(h) ((0xFU & (h)) << 4) /* Channel dst rq associated with periph handshaking ifc h */ #define ATC_SRC_REP (0x1 << 8) /* Source Replay Mod */ #define ATC_SRC_H2SEL (0x1 << 9) /* Source Handshaking Mod */ #define ATC_SRC_H2SEL_SW (0x0 << 9) #define ATC_SRC_H2SEL_HW (0x1 << 9) +#define ATC_SRC_PER_MSB(h) (ATC_PER_MSB(h) << 10) /* Channel src rq (most significant bits) */ #define ATC_DST_REP (0x1 << 12) /* Destination Replay Mod */ #define ATC_DST_H2SEL (0x1 << 13) /* Destination Handshaking Mod */ #define ATC_DST_H2SEL_SW (0x0 << 13) #define ATC_DST_H2SEL_HW (0x1 << 13) +#define ATC_DST_PER_MSB(h) (ATC_PER_MSB(h) << 14) /* Channel dst rq (most significant bits) */ #define ATC_SOD (0x1 << 16) /* Stop On Done */ #define ATC_LOCK_IF (0x1 << 20) /* Interface Lock */ #define ATC_LOCK_B (0x1 << 21) /* AHB Bus Lock */ diff --git a/include/linux/platform_data/dma-imx.h b/include/linux/platform_data/dma-imx.h index f6d30cc1cb77..beac6b8b6a7b 100644 --- a/include/linux/platform_data/dma-imx.h +++ b/include/linux/platform_data/dma-imx.h @@ -60,10 +60,8 @@ static inline int imx_dma_is_ipu(struct dma_chan *chan) static inline int imx_dma_is_general_purpose(struct dma_chan *chan) { - return strstr(dev_name(chan->device->dev), "sdma") || - !strcmp(dev_name(chan->device->dev), "imx1-dma") || - !strcmp(dev_name(chan->device->dev), "imx21-dma") || - !strcmp(dev_name(chan->device->dev), "imx27-dma"); + return !strcmp(chan->device->dev->driver->name, "imx-sdma") || + !strcmp(chan->device->dev->driver->name, "imx-dma"); } #endif diff --git a/include/linux/platform_data/dma-rcar-hpbdma.h b/include/linux/platform_data/dma-rcar-hpbdma.h new file mode 100644 index 000000000000..648b8ea61a22 --- /dev/null +++ b/include/linux/platform_data/dma-rcar-hpbdma.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2011-2013 Renesas Electronics Corporation + * Copyright (C) 2013 Cogent Embedded, Inc. + * + * 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 __DMA_RCAR_HPBDMA_H +#define __DMA_RCAR_HPBDMA_H + +#include <linux/bitops.h> +#include <linux/types.h> + +/* Transmit sizes and respective register values */ +enum { + XMIT_SZ_8BIT = 0, + XMIT_SZ_16BIT = 1, + XMIT_SZ_32BIT = 2, + XMIT_SZ_MAX +}; + +/* DMA control register (DCR) bits */ +#define HPB_DMAE_DCR_DTAMD (1u << 26) +#define HPB_DMAE_DCR_DTAC (1u << 25) +#define HPB_DMAE_DCR_DTAU (1u << 24) +#define HPB_DMAE_DCR_DTAU1 (1u << 23) +#define HPB_DMAE_DCR_SWMD (1u << 22) +#define HPB_DMAE_DCR_BTMD (1u << 21) +#define HPB_DMAE_DCR_PKMD (1u << 20) +#define HPB_DMAE_DCR_CT (1u << 18) +#define HPB_DMAE_DCR_ACMD (1u << 17) +#define HPB_DMAE_DCR_DIP (1u << 16) +#define HPB_DMAE_DCR_SMDL (1u << 13) +#define HPB_DMAE_DCR_SPDAM (1u << 12) +#define HPB_DMAE_DCR_SDRMD_MASK (3u << 10) +#define HPB_DMAE_DCR_SDRMD_MOD (0u << 10) +#define HPB_DMAE_DCR_SDRMD_AUTO (1u << 10) +#define HPB_DMAE_DCR_SDRMD_TIMER (2u << 10) +#define HPB_DMAE_DCR_SPDS_MASK (3u << 8) +#define HPB_DMAE_DCR_SPDS_8BIT (0u << 8) +#define HPB_DMAE_DCR_SPDS_16BIT (1u << 8) +#define HPB_DMAE_DCR_SPDS_32BIT (2u << 8) +#define HPB_DMAE_DCR_DMDL (1u << 5) +#define HPB_DMAE_DCR_DPDAM (1u << 4) +#define HPB_DMAE_DCR_DDRMD_MASK (3u << 2) +#define HPB_DMAE_DCR_DDRMD_MOD (0u << 2) +#define HPB_DMAE_DCR_DDRMD_AUTO (1u << 2) +#define HPB_DMAE_DCR_DDRMD_TIMER (2u << 2) +#define HPB_DMAE_DCR_DPDS_MASK (3u << 0) +#define HPB_DMAE_DCR_DPDS_8BIT (0u << 0) +#define HPB_DMAE_DCR_DPDS_16BIT (1u << 0) +#define HPB_DMAE_DCR_DPDS_32BIT (2u << 0) + +/* Asynchronous reset register (ASYNCRSTR) bits */ +#define HPB_DMAE_ASYNCRSTR_ASRST41 BIT(10) +#define HPB_DMAE_ASYNCRSTR_ASRST40 BIT(9) +#define HPB_DMAE_ASYNCRSTR_ASRST39 BIT(8) +#define HPB_DMAE_ASYNCRSTR_ASRST27 BIT(7) +#define HPB_DMAE_ASYNCRSTR_ASRST26 BIT(6) +#define HPB_DMAE_ASYNCRSTR_ASRST25 BIT(5) +#define HPB_DMAE_ASYNCRSTR_ASRST24 BIT(4) +#define HPB_DMAE_ASYNCRSTR_ASRST23 BIT(3) +#define HPB_DMAE_ASYNCRSTR_ASRST22 BIT(2) +#define HPB_DMAE_ASYNCRSTR_ASRST21 BIT(1) +#define HPB_DMAE_ASYNCRSTR_ASRST20 BIT(0) + +struct hpb_dmae_slave_config { + unsigned int id; + dma_addr_t addr; + u32 dcr; + u32 port; + u32 rstr; + u32 mdr; + u32 mdm; + u32 flags; +#define HPB_DMAE_SET_ASYNC_RESET BIT(0) +#define HPB_DMAE_SET_ASYNC_MODE BIT(1) + u32 dma_ch; +}; + +#define HPB_DMAE_CHANNEL(_irq, _s_id) \ +{ \ + .ch_irq = _irq, \ + .s_id = _s_id, \ +} + +struct hpb_dmae_channel { + unsigned int ch_irq; + unsigned int s_id; +}; + +struct hpb_dmae_pdata { + const struct hpb_dmae_slave_config *slaves; + int num_slaves; + const struct hpb_dmae_channel *channels; + int num_channels; + const unsigned int ts_shift[XMIT_SZ_MAX]; + int num_hw_channels; +}; + +#endif diff --git a/include/linux/platform_data/dma-ste-dma40.h b/include/linux/platform_data/dma-ste-dma40.h index 4b781014b0a0..1bb9b1852256 100644 --- a/include/linux/platform_data/dma-ste-dma40.h +++ b/include/linux/platform_data/dma-ste-dma40.h @@ -70,23 +70,8 @@ enum stedma40_flow_ctrl { STEDMA40_FLOW_CTRL, }; -enum stedma40_periph_data_width { - STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT, - STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT, - STEDMA40_WORD_WIDTH = STEDMA40_ESIZE_32_BIT, - STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT -}; - -enum stedma40_xfer_dir { - STEDMA40_MEM_TO_MEM = 1, - STEDMA40_MEM_TO_PERIPH, - STEDMA40_PERIPH_TO_MEM, - STEDMA40_PERIPH_TO_PERIPH -}; - - /** - * struct stedma40_chan_cfg - dst/src channel configuration + * struct stedma40_half_channel_info - dst/src channel configuration * * @big_endian: true if the src/dst should be read as big endian * @data_width: Data width of the src/dst hardware @@ -95,7 +80,7 @@ enum stedma40_xfer_dir { */ struct stedma40_half_channel_info { bool big_endian; - enum stedma40_periph_data_width data_width; + enum dma_slave_buswidth data_width; int psize; enum stedma40_flow_ctrl flow_ctrl; }; @@ -109,8 +94,7 @@ struct stedma40_half_channel_info { * version 3+, i.e DB8500v2+ * @mode: channel mode: physical, logical, or operation * @mode_opt: options for the chosen channel mode - * @src_dev_type: Src device type - * @dst_dev_type: Dst device type + * @dev_type: src/dst device type (driver uses dir to figure out which) * @src_info: Parameters for dst half channel * @dst_info: Parameters for dst half channel * @use_fixed_channel: if true, use physical channel specified by phy_channel @@ -121,13 +105,12 @@ struct stedma40_half_channel_info { * */ struct stedma40_chan_cfg { - enum stedma40_xfer_dir dir; + enum dma_transfer_direction dir; bool high_priority; bool realtime; enum stedma40_mode mode; enum stedma40_mode_opt mode_opt; - int src_dev_type; - int dst_dev_type; + int dev_type; struct stedma40_half_channel_info src_info; struct stedma40_half_channel_info dst_info; @@ -138,13 +121,8 @@ struct stedma40_chan_cfg { /** * struct stedma40_platform_data - Configuration struct for the dma device. * - * @dev_len: length of dev_tx and dev_rx * @dev_tx: mapping between destination event line and io address * @dev_rx: mapping between source event line and io address - * @memcpy: list of memcpy event lines - * @memcpy_len: length of memcpy - * @memcpy_conf_phy: default configuration of physical channel memcpy - * @memcpy_conf_log: default configuration of logical channel memcpy * @disabled_channels: A vector, ending with -1, that marks physical channels * that are for different reasons not available for the driver. * @soft_lli_chans: A vector, that marks physical channels will use LLI by SW @@ -154,22 +132,17 @@ struct stedma40_chan_cfg { * @num_of_soft_lli_chans: The number of channels that needs to be configured * to use SoftLLI. * @use_esram_lcla: flag for mapping the lcla into esram region + * @num_of_memcpy_chans: The number of channels reserved for memcpy. * @num_of_phy_chans: The number of physical channels implemented in HW. * 0 means reading the number of channels from DMA HW but this is only valid * for 'multiple of 4' channels, like 8. */ struct stedma40_platform_data { - u32 dev_len; - const dma_addr_t *dev_tx; - const dma_addr_t *dev_rx; - int *memcpy; - u32 memcpy_len; - struct stedma40_chan_cfg *memcpy_conf_phy; - struct stedma40_chan_cfg *memcpy_conf_log; int disabled_channels[STEDMA40_MAX_PHYS]; int *soft_lli_chans; int num_of_soft_lli_chans; bool use_esram_lcla; + int num_of_memcpy_chans; int num_of_phy_chans; }; diff --git a/include/linux/platform_data/dwc3-omap.h b/include/linux/platform_data/dwc3-omap.h index ada401244e0b..1d36ca874cc8 100644 --- a/include/linux/platform_data/dwc3-omap.h +++ b/include/linux/platform_data/dwc3-omap.h @@ -41,7 +41,3 @@ enum dwc3_omap_utmi_mode { DWC3_OMAP_UTMI_MODE_HW, DWC3_OMAP_UTMI_MODE_SW, }; - -struct dwc3_omap_data { - enum dwc3_omap_utmi_mode utmi_mode; -}; diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h new file mode 100644 index 000000000000..179fb91bb5f2 --- /dev/null +++ b/include/linux/platform_data/edma.h @@ -0,0 +1,185 @@ +/* + * TI EDMA definitions + * + * Copyright (C) 2006-2013 Texas Instruments. + * + * 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. + */ + +/* + * This EDMA3 programming framework exposes two basic kinds of resource: + * + * Channel Triggers transfers, usually from a hardware event but + * also manually or by "chaining" from DMA completions. + * Each channel is coupled to a Parameter RAM (PaRAM) slot. + * + * Slot Each PaRAM slot holds a DMA transfer descriptor (PaRAM + * "set"), source and destination addresses, a link to a + * next PaRAM slot (if any), options for the transfer, and + * instructions for updating those addresses. There are + * more than twice as many slots as event channels. + * + * Each PaRAM set describes a sequence of transfers, either for one large + * buffer or for several discontiguous smaller buffers. An EDMA transfer + * is driven only from a channel, which performs the transfers specified + * in its PaRAM slot until there are no more transfers. When that last + * transfer completes, the "link" field may be used to reload the channel's + * PaRAM slot with a new transfer descriptor. + * + * The EDMA Channel Controller (CC) maps requests from channels into physical + * Transfer Controller (TC) requests when the channel triggers (by hardware + * or software events, or by chaining). The two physical DMA channels provided + * by the TCs are thus shared by many logical channels. + * + * DaVinci hardware also has a "QDMA" mechanism which is not currently + * supported through this interface. (DSP firmware uses it though.) + */ + +#ifndef EDMA_H_ +#define EDMA_H_ + +/* PaRAM slots are laid out like this */ +struct edmacc_param { + unsigned int opt; + unsigned int src; + unsigned int a_b_cnt; + unsigned int dst; + unsigned int src_dst_bidx; + unsigned int link_bcntrld; + unsigned int src_dst_cidx; + unsigned int ccnt; +}; + +/* fields in edmacc_param.opt */ +#define SAM BIT(0) +#define DAM BIT(1) +#define SYNCDIM BIT(2) +#define STATIC BIT(3) +#define EDMA_FWID (0x07 << 8) +#define TCCMODE BIT(11) +#define EDMA_TCC(t) ((t) << 12) +#define TCINTEN BIT(20) +#define ITCINTEN BIT(21) +#define TCCHEN BIT(22) +#define ITCCHEN BIT(23) + +/*ch_status paramater of callback function possible values*/ +#define DMA_COMPLETE 1 +#define DMA_CC_ERROR 2 +#define DMA_TC1_ERROR 3 +#define DMA_TC2_ERROR 4 + +enum address_mode { + INCR = 0, + FIFO = 1 +}; + +enum fifo_width { + W8BIT = 0, + W16BIT = 1, + W32BIT = 2, + W64BIT = 3, + W128BIT = 4, + W256BIT = 5 +}; + +enum dma_event_q { + EVENTQ_0 = 0, + EVENTQ_1 = 1, + EVENTQ_2 = 2, + EVENTQ_3 = 3, + EVENTQ_DEFAULT = -1 +}; + +enum sync_dimension { + ASYNC = 0, + ABSYNC = 1 +}; + +#define EDMA_CTLR_CHAN(ctlr, chan) (((ctlr) << 16) | (chan)) +#define EDMA_CTLR(i) ((i) >> 16) +#define EDMA_CHAN_SLOT(i) ((i) & 0xffff) + +#define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */ +#define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */ +#define EDMA_CONT_PARAMS_ANY 1001 +#define EDMA_CONT_PARAMS_FIXED_EXACT 1002 +#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003 + +#define EDMA_MAX_CC 2 + +/* alloc/free DMA channels and their dedicated parameter RAM slots */ +int edma_alloc_channel(int channel, + void (*callback)(unsigned channel, u16 ch_status, void *data), + void *data, enum dma_event_q); +void edma_free_channel(unsigned channel); + +/* alloc/free parameter RAM slots */ +int edma_alloc_slot(unsigned ctlr, int slot); +void edma_free_slot(unsigned slot); + +/* alloc/free a set of contiguous parameter RAM slots */ +int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count); +int edma_free_cont_slots(unsigned slot, int count); + +/* calls that operate on part of a parameter RAM slot */ +void edma_set_src(unsigned slot, dma_addr_t src_port, + enum address_mode mode, enum fifo_width); +void edma_set_dest(unsigned slot, dma_addr_t dest_port, + enum address_mode mode, enum fifo_width); +void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst); +void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx); +void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx); +void edma_set_transfer_params(unsigned slot, u16 acnt, u16 bcnt, u16 ccnt, + u16 bcnt_rld, enum sync_dimension sync_mode); +void edma_link(unsigned from, unsigned to); +void edma_unlink(unsigned from); + +/* calls that operate on an entire parameter RAM slot */ +void edma_write_slot(unsigned slot, const struct edmacc_param *params); +void edma_read_slot(unsigned slot, struct edmacc_param *params); + +/* channel control operations */ +int edma_start(unsigned channel); +void edma_stop(unsigned channel); +void edma_clean_channel(unsigned channel); +void edma_clear_event(unsigned channel); +void edma_pause(unsigned channel); +void edma_resume(unsigned channel); + +struct edma_rsv_info { + + const s16 (*rsv_chans)[2]; + const s16 (*rsv_slots)[2]; +}; + +/* platform_data for EDMA driver */ +struct edma_soc_info { + + /* how many dma resources of each type */ + unsigned n_channel; + unsigned n_region; + unsigned n_slot; + unsigned n_tc; + unsigned n_cc; + /* + * Default queue is expected to be a low-priority queue. + * This way, long transfers on the default queue started + * by the codec engine will not cause audio defects. + */ + enum dma_event_q default_queue; + + /* Resource reservation for other cores */ + struct edma_rsv_info *rsv; + + s8 (*queue_tc_mapping)[2]; + s8 (*queue_priority_mapping)[2]; + const s16 (*xbar_chans)[2]; +}; + +int edma_trigger_channel(unsigned); + +#endif diff --git a/include/linux/platform_data/efm32-spi.h b/include/linux/platform_data/efm32-spi.h new file mode 100644 index 000000000000..31b19ca1d73a --- /dev/null +++ b/include/linux/platform_data/efm32-spi.h @@ -0,0 +1,14 @@ +#ifndef __LINUX_PLATFORM_DATA_EFM32_SPI_H__ +#define __LINUX_PLATFORM_DATA_EFM32_SPI_H__ + +#include <linux/types.h> + +/** + * struct efm32_spi_pdata + * @location: pinmux location for the I/O pins (to be written to the ROUTE + * register) + */ +struct efm32_spi_pdata { + u8 location; +}; +#endif /* ifndef __LINUX_PLATFORM_DATA_EFM32_SPI_H__ */ diff --git a/include/linux/platform_data/elm.h b/include/linux/platform_data/elm.h index 1bd5244d1dcd..bf0a83b7ed9d 100644 --- a/include/linux/platform_data/elm.h +++ b/include/linux/platform_data/elm.h @@ -50,5 +50,5 @@ struct elm_errorvec { void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc, struct elm_errorvec *err_vec); -void elm_config(struct device *dev, enum bch_ecc bch_type); +int elm_config(struct device *dev, enum bch_ecc bch_type); #endif /* __ELM_H */ diff --git a/include/linux/platform_data/emif_plat.h b/include/linux/platform_data/emif_plat.h index 03378ca84061..5c19a2a647c4 100644 --- a/include/linux/platform_data/emif_plat.h +++ b/include/linux/platform_data/emif_plat.h @@ -40,6 +40,7 @@ /* Custom config requests */ #define EMIF_CUSTOM_CONFIG_LPMODE 0x00000001 #define EMIF_CUSTOM_CONFIG_TEMP_ALERT_POLL_INTERVAL 0x00000002 +#define EMIF_CUSTOM_CONFIG_EXTENDED_TEMP_PART 0x00000004 #ifndef __ASSEMBLY__ /** diff --git a/include/linux/platform_data/exynos_thermal.h b/include/linux/platform_data/exynos_thermal.h deleted file mode 100644 index da7e6274b175..000000000000 --- a/include/linux/platform_data/exynos_thermal.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * exynos_thermal.h - Samsung EXYNOS TMU (Thermal Management Unit) - * - * Copyright (C) 2011 Samsung Electronics - * Donggeun Kim <dg77.kim@samsung.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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _LINUX_EXYNOS_THERMAL_H -#define _LINUX_EXYNOS_THERMAL_H -#include <linux/cpu_cooling.h> - -enum calibration_type { - TYPE_ONE_POINT_TRIMMING, - TYPE_TWO_POINT_TRIMMING, - TYPE_NONE, -}; - -enum soc_type { - SOC_ARCH_EXYNOS4210 = 1, - SOC_ARCH_EXYNOS, -}; -/** - * struct freq_clip_table - * @freq_clip_max: maximum frequency allowed for this cooling state. - * @temp_level: Temperature level at which the temperature clipping will - * happen. - * @mask_val: cpumask of the allowed cpu's where the clipping will take place. - * - * This structure is required to be filled and passed to the - * cpufreq_cooling_unregister function. - */ -struct freq_clip_table { - unsigned int freq_clip_max; - unsigned int temp_level; - const struct cpumask *mask_val; -}; - -/** - * struct exynos_tmu_platform_data - * @threshold: basic temperature for generating interrupt - * 25 <= threshold <= 125 [unit: degree Celsius] - * @threshold_falling: differntial value for setting threshold - * of temperature falling interrupt. - * @trigger_levels: array for each interrupt levels - * [unit: degree Celsius] - * 0: temperature for trigger_level0 interrupt - * condition for trigger_level0 interrupt: - * current temperature > threshold + trigger_levels[0] - * 1: temperature for trigger_level1 interrupt - * condition for trigger_level1 interrupt: - * current temperature > threshold + trigger_levels[1] - * 2: temperature for trigger_level2 interrupt - * condition for trigger_level2 interrupt: - * current temperature > threshold + trigger_levels[2] - * 3: temperature for trigger_level3 interrupt - * condition for trigger_level3 interrupt: - * current temperature > threshold + trigger_levels[3] - * @trigger_level0_en: - * 1 = enable trigger_level0 interrupt, - * 0 = disable trigger_level0 interrupt - * @trigger_level1_en: - * 1 = enable trigger_level1 interrupt, - * 0 = disable trigger_level1 interrupt - * @trigger_level2_en: - * 1 = enable trigger_level2 interrupt, - * 0 = disable trigger_level2 interrupt - * @trigger_level3_en: - * 1 = enable trigger_level3 interrupt, - * 0 = disable trigger_level3 interrupt - * @gain: gain of amplifier in the positive-TC generator block - * 0 <= gain <= 15 - * @reference_voltage: reference voltage of amplifier - * in the positive-TC generator block - * 0 <= reference_voltage <= 31 - * @noise_cancel_mode: noise cancellation mode - * 000, 100, 101, 110 and 111 can be different modes - * @type: determines the type of SOC - * @efuse_value: platform defined fuse value - * @cal_type: calibration type for temperature - * @freq_clip_table: Table representing frequency reduction percentage. - * @freq_tab_count: Count of the above table as frequency reduction may - * applicable to only some of the trigger levels. - * - * This structure is required for configuration of exynos_tmu driver. - */ -struct exynos_tmu_platform_data { - u8 threshold; - u8 threshold_falling; - u8 trigger_levels[4]; - bool trigger_level0_en; - bool trigger_level1_en; - bool trigger_level2_en; - bool trigger_level3_en; - - u8 gain; - u8 reference_voltage; - u8 noise_cancel_mode; - u32 efuse_value; - - enum calibration_type cal_type; - enum soc_type type; - struct freq_clip_table freq_tab[4]; - unsigned int freq_tab_count; -}; -#endif /* _LINUX_EXYNOS_THERMAL_H */ diff --git a/include/linux/platform_data/g762.h b/include/linux/platform_data/g762.h new file mode 100644 index 000000000000..d3c51283764d --- /dev/null +++ b/include/linux/platform_data/g762.h @@ -0,0 +1,37 @@ +/* + * Platform data structure for g762 fan controller driver + * + * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __LINUX_PLATFORM_DATA_G762_H__ +#define __LINUX_PLATFORM_DATA_G762_H__ + +/* + * Following structure can be used to set g762 driver platform specific data + * during board init. Note that passing a sparse structure is possible but + * will result in non-specified attributes to be set to default value, hence + * overloading those installed during boot (e.g. by u-boot). + */ + +struct g762_platform_data { + u32 fan_startv; + u32 fan_gear_mode; + u32 pwm_polarity; + u32 clk_freq; +}; + +#endif /* __LINUX_PLATFORM_DATA_G762_H__ */ diff --git a/include/linux/platform_data/gpio-em.h b/include/linux/platform_data/gpio-em.h index 573edfb046c4..7c5a519d2dcd 100644 --- a/include/linux/platform_data/gpio-em.h +++ b/include/linux/platform_data/gpio-em.h @@ -5,6 +5,7 @@ struct gpio_em_config { unsigned int gpio_base; unsigned int irq_base; unsigned int number_of_pins; + const char *pctl_name; }; #endif /* __GPIO_EM_H__ */ diff --git a/include/linux/platform_data/gpio-rcar.h b/include/linux/platform_data/gpio-rcar.h new file mode 100644 index 000000000000..2d8d69432813 --- /dev/null +++ b/include/linux/platform_data/gpio-rcar.h @@ -0,0 +1,29 @@ +/* + * Renesas R-Car GPIO Support + * + * Copyright (C) 2013 Magnus Damm + * + * 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 + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __GPIO_RCAR_H__ +#define __GPIO_RCAR_H__ + +struct gpio_rcar_config { + int gpio_base; + unsigned int irq_base; + unsigned int number_of_pins; + const char *pctl_name; + unsigned has_both_edge_trigger:1; +}; + +#define RCAR_GP_PIN(bank, pin) (((bank) * 32) + (pin)) + +#endif /* __GPIO_RCAR_H__ */ diff --git a/include/linux/platform_data/gpio_backlight.h b/include/linux/platform_data/gpio_backlight.h new file mode 100644 index 000000000000..5ae0d9c80d4d --- /dev/null +++ b/include/linux/platform_data/gpio_backlight.h @@ -0,0 +1,21 @@ +/* + * gpio_backlight.h - Simple GPIO-controlled backlight + * + * 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 __GPIO_BACKLIGHT_H__ +#define __GPIO_BACKLIGHT_H__ + +struct device; + +struct gpio_backlight_platform_data { + struct device *fbdev; + int gpio; + int def_value; + bool active_low; + const char *name; +}; + +#endif diff --git a/include/linux/platform_data/imx-iram.h b/include/linux/platform_data/imx-iram.h deleted file mode 100644 index 022690c33702..000000000000 --- a/include/linux/platform_data/imx-iram.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -#include <linux/errno.h> - -#ifdef CONFIG_IRAM_ALLOC - -int __init iram_init(unsigned long base, unsigned long size); -void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr); -void iram_free(unsigned long dma_addr, unsigned int size); - -#else - -static inline int __init iram_init(unsigned long base, unsigned long size) -{ - return -ENOMEM; -} - -static inline void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) -{ - return NULL; -} - -static inline void iram_free(unsigned long base, unsigned long size) {} - -#endif diff --git a/include/linux/platform_data/irq-renesas-intc-irqpin.h b/include/linux/platform_data/irq-renesas-intc-irqpin.h new file mode 100644 index 000000000000..e4cb911066a6 --- /dev/null +++ b/include/linux/platform_data/irq-renesas-intc-irqpin.h @@ -0,0 +1,29 @@ +/* + * Renesas INTC External IRQ Pin Driver + * + * Copyright (C) 2013 Magnus Damm + * + * 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 + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __IRQ_RENESAS_INTC_IRQPIN_H__ +#define __IRQ_RENESAS_INTC_IRQPIN_H__ + +struct renesas_intc_irqpin_config { + unsigned int sense_bitfield_width; + unsigned int irq_base; + bool control_parent; +}; + +#endif /* __IRQ_RENESAS_INTC_IRQPIN_H__ */ diff --git a/include/linux/clk/mvebu.h b/include/linux/platform_data/irq-renesas-irqc.h index 8c4ae713b063..3ae17b3e00ed 100644 --- a/include/linux/clk/mvebu.h +++ b/include/linux/platform_data/irq-renesas-irqc.h @@ -1,8 +1,11 @@ /* + * Renesas IRQC Driver + * + * Copyright (C) 2013 Magnus Damm + * * 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. + * the Free Software Foundation; either version 2 of the License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,9 +17,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __CLK_MVEBU_H_ -#define __CLK_MVEBU_H_ +#ifndef __IRQ_RENESAS_IRQC_H__ +#define __IRQ_RENESAS_IRQC_H__ -void __init mvebu_clocks_init(void); +struct renesas_irqc_config { + unsigned int irq_base; +}; -#endif +#endif /* __IRQ_RENESAS_IRQC_H__ */ diff --git a/include/linux/platform_data/keypad-pxa27x.h b/include/linux/platform_data/keypad-pxa27x.h index 5ce8d5e6ea51..24625569d16d 100644 --- a/include/linux/platform_data/keypad-pxa27x.h +++ b/include/linux/platform_data/keypad-pxa27x.h @@ -36,10 +36,9 @@ struct pxa27x_keypad_platform_data { /* code map for the matrix keys */ + const struct matrix_keymap_data *matrix_keymap_data; unsigned int matrix_key_rows; unsigned int matrix_key_cols; - unsigned int *matrix_key_map; - int matrix_key_map_size; /* direct keys */ int direct_key_num; diff --git a/include/linux/platform_data/leds-lp55xx.h b/include/linux/platform_data/leds-lp55xx.h index 1509570d5a3f..c32de4dcec54 100644 --- a/include/linux/platform_data/leds-lp55xx.h +++ b/include/linux/platform_data/leds-lp55xx.h @@ -20,34 +20,30 @@ #define LP55XX_CLOCK_INT 1 #define LP55XX_CLOCK_EXT 2 -/* Bits in LP5521 CONFIG register. 'update_config' in lp55xx_platform_data */ -#define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */ -#define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */ -#define LP5521_CP_MODE_OFF 0 /* Charge pump (CP) off */ -#define LP5521_CP_MODE_BYPASS 8 /* CP forced to bypass mode */ -#define LP5521_CP_MODE_1X5 0x10 /* CP forced to 1.5x mode */ -#define LP5521_CP_MODE_AUTO 0x18 /* Automatic mode selection */ -#define LP5521_R_TO_BATT 4 /* R out: 0 = CP, 1 = Vbat */ -#define LP5521_CLK_SRC_EXT 0 /* Ext-clk source (CLK_32K) */ -#define LP5521_CLK_INT 1 /* Internal clock */ -#define LP5521_CLK_AUTO 2 /* Automatic clock selection */ - struct lp55xx_led_config { const char *name; + const char *default_trigger; u8 chan_nr; u8 led_current; /* mA x10, 0 if led is not connected */ u8 max_current; }; struct lp55xx_predef_pattern { - u8 *r; - u8 *g; - u8 *b; + const u8 *r; + const u8 *g; + const u8 *b; u8 size_r; u8 size_g; u8 size_b; }; +enum lp8501_pwr_sel { + LP8501_ALL_VDD, /* D1~9 are connected to VDD */ + LP8501_6VDD_3VOUT, /* D1~6 with VDD, D7~9 with VOUT */ + LP8501_3VDD_6VOUT, /* D1~6 with VOUT, D7~9 with VDD */ + LP8501_ALL_VOUT, /* D1~9 are connected to VOUT */ +}; + /* * struct lp55xx_platform_data * @led_config : Configurable led class device @@ -80,8 +76,8 @@ struct lp55xx_platform_data { struct lp55xx_predef_pattern *patterns; unsigned int num_patterns; - /* _CONFIG register */ - u8 update_config; + /* LP8501 specific */ + enum lp8501_pwr_sel pwr_sel; }; #endif /* _LEDS_LP55XX_H */ diff --git a/include/linux/platform_data/leds-pca9633.h b/include/linux/platform_data/leds-pca963x.h index c5bf29b6fa7f..e731f0036329 100644 --- a/include/linux/platform_data/leds-pca9633.h +++ b/include/linux/platform_data/leds-pca963x.h @@ -1,7 +1,8 @@ /* - * PCA9633 LED chip driver. + * PCA963X LED chip driver. * * Copyright 2012 bct electronic GmbH + * Copyright 2013 Qtechnology A/S * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -18,18 +19,24 @@ * 02110-1301 USA */ -#ifndef __LINUX_PCA9633_H -#define __LINUX_PCA9633_H +#ifndef __LINUX_PCA963X_H +#define __LINUX_PCA963X_H #include <linux/leds.h> -enum pca9633_outdrv { - PCA9633_OPEN_DRAIN, - PCA9633_TOTEM_POLE, /* aka push-pull */ +enum pca963x_outdrv { + PCA963X_OPEN_DRAIN, + PCA963X_TOTEM_POLE, /* aka push-pull */ }; -struct pca9633_platform_data { +enum pca963x_blink_type { + PCA963X_SW_BLINK, + PCA963X_HW_BLINK, +}; + +struct pca963x_platform_data { struct led_platform_data leds; - enum pca9633_outdrv outdrv; + enum pca963x_outdrv outdrv; + enum pca963x_blink_type blink_type; }; -#endif /* __LINUX_PCA9633_H*/ +#endif /* __LINUX_PCA963X_H*/ diff --git a/include/linux/platform_data/leds-renesas-tpu.h b/include/linux/platform_data/leds-renesas-tpu.h deleted file mode 100644 index 055387086fc1..000000000000 --- a/include/linux/platform_data/leds-renesas-tpu.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __LEDS_RENESAS_TPU_H__ -#define __LEDS_RENESAS_TPU_H__ - -struct led_renesas_tpu_config { - char *name; - unsigned pin_gpio_fn; - unsigned pin_gpio; - unsigned int channel_offset; - unsigned int timer_bit; - unsigned int max_brightness; - unsigned int refresh_rate; -}; - -#endif /* __LEDS_RENESAS_TPU_H__ */ diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h index 20ee8b221dbd..ea3200527dd3 100644 --- a/include/linux/platform_data/lp855x.h +++ b/include/linux/platform_data/lp855x.h @@ -69,11 +69,6 @@ enum lp855x_chip_id { LP8557, }; -enum lp855x_brightness_ctrl_mode { - PWM_BASED = 1, - REGISTER_BASED, -}; - enum lp8550_brighntess_source { LP8550_PWM_ONLY, LP8550_I2C_ONLY = 2, @@ -116,24 +111,18 @@ struct lp855x_rom_data { /** * struct lp855x_platform_data * @name : Backlight driver name. If it is not defined, default name is set. - * @mode : brightness control by pwm or lp855x register * @device_control : value of DEVICE CONTROL register * @initial_brightness : initial value of backlight brightness * @period_ns : platform specific pwm period value. unit is nano. Only valid when mode is PWM_BASED. - * @load_new_rom_data : - 0 : use default configuration data - 1 : update values of eeprom or eprom registers on loading driver * @size_program : total size of lp855x_rom_data * @rom_data : list of new eeprom/eprom registers */ struct lp855x_platform_data { - char *name; - enum lp855x_brightness_ctrl_mode mode; + const char *name; u8 device_control; - int initial_brightness; + u8 initial_brightness; unsigned int period_ns; - u8 load_new_rom_data; int size_program; struct lp855x_rom_data *rom_data; }; diff --git a/include/linux/platform_data/lv5207lp.h b/include/linux/platform_data/lv5207lp.h new file mode 100644 index 000000000000..7dc4d9a219a6 --- /dev/null +++ b/include/linux/platform_data/lv5207lp.h @@ -0,0 +1,19 @@ +/* + * lv5207lp.h - Sanyo LV5207LP LEDs Driver + * + * 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 __LV5207LP_H__ +#define __LV5207LP_H__ + +struct device; + +struct lv5207lp_platform_data { + struct device *fbdev; + unsigned int max_value; + unsigned int def_value; +}; + +#endif diff --git a/include/linux/platform_data/mailbox-omap.h b/include/linux/platform_data/mailbox-omap.h new file mode 100644 index 000000000000..4631dbb4255e --- /dev/null +++ b/include/linux/platform_data/mailbox-omap.h @@ -0,0 +1,58 @@ +/* + * mailbox-omap.h + * + * Copyright (C) 2013 Texas Instruments, Inc. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _PLAT_MAILBOX_H +#define _PLAT_MAILBOX_H + +/* Interrupt register configuration types */ +#define MBOX_INTR_CFG_TYPE1 (0) +#define MBOX_INTR_CFG_TYPE2 (1) + +/** + * struct omap_mbox_dev_info - OMAP mailbox device attribute info + * @name: name of the mailbox device + * @tx_id: mailbox queue id used for transmitting messages + * @rx_id: mailbox queue id on which messages are received + * @irq_id: irq identifier number to use from the hwmod data + * @usr_id: mailbox user id for identifying the interrupt into + * the MPU interrupt controller. + */ +struct omap_mbox_dev_info { + const char *name; + u32 tx_id; + u32 rx_id; + u32 irq_id; + u32 usr_id; +}; + +/** + * struct omap_mbox_pdata - OMAP mailbox platform data + * @intr_type: type of interrupt configuration registers used + while programming mailbox queue interrupts + * @num_users: number of users (processor devices) that the mailbox + * h/w block can interrupt + * @num_fifos: number of h/w fifos within the mailbox h/w block + * @info_cnt: number of mailbox devices for the platform + * @info: array of mailbox device attributes + */ +struct omap_mbox_pdata { + u32 intr_type; + u32 num_users; + u32 num_fifos; + u32 info_cnt; + struct omap_mbox_dev_info *info; +}; + +#endif /* _PLAT_MAILBOX_H */ diff --git a/include/linux/platform_data/max310x.h b/include/linux/platform_data/max310x.h index 91648bf5fc5c..dd11dcd1a184 100644 --- a/include/linux/platform_data/max310x.h +++ b/include/linux/platform_data/max310x.h @@ -1,5 +1,5 @@ /* - * Maxim (Dallas) MAX3107/8 serial driver + * Maxim (Dallas) MAX3107/8/9, MAX14830 serial driver * * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> * @@ -37,14 +37,13 @@ * }; */ -#define MAX310X_MAX_UARTS 1 +#define MAX310X_MAX_UARTS 4 /* MAX310X platform data structure */ struct max310x_pdata { /* Flags global to driver */ - const u8 driver_flags:2; + const u8 driver_flags; #define MAX310X_EXT_CLK (0x00000001) /* External clock enable */ -#define MAX310X_AUTOSLEEP (0x00000002) /* Enable AutoSleep mode */ /* Flags global to UART port */ const u8 uart_flags[MAX310X_MAX_UARTS]; #define MAX310X_LOOPBACK (0x00000001) /* Loopback mode enable */ @@ -60,8 +59,6 @@ struct max310x_pdata { void (*init)(void); /* Called before finish */ void (*exit)(void); - /* Suspend callback */ - void (*suspend)(int do_suspend); }; #endif diff --git a/include/linux/platform_data/mmc-davinci.h b/include/linux/platform_data/mmc-davinci.h index 5ba6b22ce338..9cea4ee377b5 100644 --- a/include/linux/platform_data/mmc-davinci.h +++ b/include/linux/platform_data/mmc-davinci.h @@ -23,9 +23,6 @@ struct davinci_mmc_config { /* any additional host capabilities: OR'd in to mmc->f_caps */ u32 caps; - /* Version of the MMC/SD controller */ - u8 version; - /* Number of sg segments */ u8 nr_sg; }; diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h index b4a0521ce411..a0f5a8f9b3bc 100644 --- a/include/linux/platform_data/mmc-esdhc-imx.h +++ b/include/linux/platform_data/mmc-esdhc-imx.h @@ -10,6 +10,8 @@ #ifndef __ASM_ARCH_IMX_ESDHC_H #define __ASM_ARCH_IMX_ESDHC_H +#include <linux/types.h> + enum wp_types { ESDHC_WP_NONE, /* no WP, neither controller nor gpio */ ESDHC_WP_CONTROLLER, /* mmc controller internal WP */ @@ -32,6 +34,7 @@ enum cd_types { * @cd_gpio: gpio for card_detect interrupt * @wp_type: type of write_protect method (see wp_types enum above) * @cd_type: type of card_detect method (see cd_types enum above) + * @support_vsel: indicate it supports 1.8v switching */ struct esdhc_platform_data { @@ -40,5 +43,7 @@ struct esdhc_platform_data { enum wp_types wp_type; enum cd_types cd_type; int max_bus_width; + unsigned int f_max; + bool support_vsel; }; #endif /* __ASM_ARCH_IMX_ESDHC_H */ diff --git a/include/linux/platform_data/mmc-pxamci.h b/include/linux/platform_data/mmc-pxamci.h index 9eb515bb799d..1706b3597ce0 100644 --- a/include/linux/platform_data/mmc-pxamci.h +++ b/include/linux/platform_data/mmc-pxamci.h @@ -12,7 +12,7 @@ struct pxamci_platform_data { unsigned long detect_delay_ms; /* delay in millisecond before detecting cards after interrupt */ int (*init)(struct device *, irq_handler_t , void *); int (*get_ro)(struct device *); - void (*setpower)(struct device *, unsigned int); + int (*setpower)(struct device *, unsigned int); void (*exit)(struct device *, void *); int gpio_card_detect; /* gpio detecting card insertion */ int gpio_card_ro; /* gpio detecting read only toggle */ diff --git a/include/linux/platform_data/mmc-sdhci-s3c.h b/include/linux/platform_data/mmc-sdhci-s3c.h new file mode 100644 index 000000000000..249f02387a35 --- /dev/null +++ b/include/linux/platform_data/mmc-sdhci-s3c.h @@ -0,0 +1,56 @@ +#ifndef __PLATFORM_DATA_SDHCI_S3C_H +#define __PLATFORM_DATA_SDHCI_S3C_H + +struct platform_device; + +enum cd_types { + S3C_SDHCI_CD_INTERNAL, /* use mmc internal CD line */ + S3C_SDHCI_CD_EXTERNAL, /* use external callback */ + S3C_SDHCI_CD_GPIO, /* use external gpio pin for CD line */ + S3C_SDHCI_CD_NONE, /* no CD line, use polling to detect card */ + S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */ +}; + +/** + * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI + * @max_width: The maximum number of data bits supported. + * @host_caps: Standard MMC host capabilities bit field. + * @host_caps2: The second standard MMC host capabilities bit field. + * @cd_type: Type of Card Detection method (see cd_types enum above) + * @ext_cd_init: Initialize external card detect subsystem. Called on + * sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL. + * notify_func argument is a callback to the sdhci-s3c driver + * that triggers the card detection event. Callback arguments: + * dev is pointer to platform device of the host controller, + * state is new state of the card (0 - removed, 1 - inserted). + * @ext_cd_cleanup: Cleanup external card detect subsystem. Called on + * sdhci-s3c driver remove when cd_type == S3C_SDHCI_CD_EXTERNAL. + * notify_func argument is the same callback as for ext_cd_init. + * @ext_cd_gpio: gpio pin used for external CD line, valid only if + * cd_type == S3C_SDHCI_CD_GPIO + * @ext_cd_gpio_invert: invert values for external CD gpio line + * @cfg_gpio: Configure the GPIO for a specific card bit-width + * + * Initialisation data specific to either the machine or the platform + * for the device driver to use or call-back when configuring gpio or + * card speed information. +*/ +struct s3c_sdhci_platdata { + unsigned int max_width; + unsigned int host_caps; + unsigned int host_caps2; + unsigned int pm_caps; + enum cd_types cd_type; + + int ext_cd_gpio; + bool ext_cd_gpio_invert; + int (*ext_cd_init)(void (*notify_func)(struct platform_device *, + int state)); + int (*ext_cd_cleanup)(void (*notify_func)(struct platform_device *, + int state)); + + void (*cfg_gpio)(struct platform_device *dev, int width); +}; + + +#endif /* __PLATFORM_DATA_SDHCI_S3C_H */ diff --git a/include/linux/platform_data/mtd-nand-pxa3xx.h b/include/linux/platform_data/mtd-nand-pxa3xx.h index c42f39f20195..ffb801998e5d 100644 --- a/include/linux/platform_data/mtd-nand-pxa3xx.h +++ b/include/linux/platform_data/mtd-nand-pxa3xx.h @@ -16,19 +16,6 @@ struct pxa3xx_nand_timing { unsigned int tAR; /* ND_ALE low to ND_nRE low delay */ }; -struct pxa3xx_nand_cmdset { - uint16_t read1; - uint16_t read2; - uint16_t program; - uint16_t read_status; - uint16_t read_id; - uint16_t erase; - uint16_t reset; - uint16_t lock; - uint16_t unlock; - uint16_t lock_status; -}; - struct pxa3xx_nand_flash { char *name; uint32_t chip_id; diff --git a/include/linux/platform_data/mv_usb.h b/include/linux/platform_data/mv_usb.h index 944b01dd103e..98b7925f1a2d 100644 --- a/include/linux/platform_data/mv_usb.h +++ b/include/linux/platform_data/mv_usb.h @@ -34,8 +34,6 @@ struct mv_usb_addon_irq { }; struct mv_usb_platform_data { - unsigned int clknum; - char **clkname; struct mv_usb_addon_irq *id; /* Only valid for OTG. ID pin change*/ struct mv_usb_addon_irq *vbus; /* valid for OTG/UDC. VBUS change*/ diff --git a/include/linux/platform_data/net-cw1200.h b/include/linux/platform_data/net-cw1200.h new file mode 100644 index 000000000000..c6fbc3ce4ab0 --- /dev/null +++ b/include/linux/platform_data/net-cw1200.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com> + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef CW1200_PLAT_H_INCLUDED +#define CW1200_PLAT_H_INCLUDED + +struct cw1200_platform_data_spi { + u8 spi_bits_per_word; /* REQUIRED */ + u16 ref_clk; /* REQUIRED (in KHz) */ + + /* All others are optional */ + bool have_5ghz; + int reset; /* GPIO to RSTn signal (0 disables) */ + int powerup; /* GPIO to POWERUP signal (0 disables) */ + int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata, + bool enable); /* Control 3v3 / 1v8 supply */ + int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata, + bool enable); /* Control CLK32K */ + const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */ + const char *sdd_file; /* if NULL, will use default for detected hw type */ +}; + +struct cw1200_platform_data_sdio { + u16 ref_clk; /* REQUIRED (in KHz) */ + + /* All others are optional */ + bool have_5ghz; + bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */ + int reset; /* GPIO to RSTn signal (0 disables) */ + int powerup; /* GPIO to POWERUP signal (0 disables) */ + int irq; /* IRQ line or 0 to use SDIO IRQ */ + int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata, + bool enable); /* Control 3v3 / 1v8 supply */ + int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata, + bool enable); /* Control CLK32K */ + const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */ + const char *sdd_file; /* if NULL, will use default for detected hw type */ +}; + + +/* An example of SPI support in your board setup file: + + static struct cw1200_platform_data_spi cw1200_platform_data = { + .ref_clk = 38400, + .spi_bits_per_word = 16, + .reset = GPIO_RF_RESET, + .powerup = GPIO_RF_POWERUP, + .macaddr = wifi_mac_addr, + .sdd_file = "sdd_sagrad_1091_1098.bin", + }; + static struct spi_board_info myboard_spi_devices[] __initdata = { + { + .modalias = "cw1200_wlan_spi", + .max_speed_hz = 52000000, + .bus_num = 0, + .irq = WIFI_IRQ, + .platform_data = &cw1200_platform_data, + .chip_select = 0, + }, + }; + + */ + +/* An example of SDIO support in your board setup file: + + static struct cw1200_platform_data_sdio my_cw1200_platform_data = { + .ref_clk = 38400, + .have_5ghz = false, + .sdd_file = "sdd_myplatform.bin", + }; + cw1200_sdio_set_platform_data(&my_cw1200_platform_data); + + */ + +void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata); + +#endif /* CW1200_PLAT_H_INCLUDED */ diff --git a/include/linux/platform_data/ntc_thermistor.h b/include/linux/platform_data/ntc_thermistor.h index 88734e871e3a..c7285b575462 100644 --- a/include/linux/platform_data/ntc_thermistor.h +++ b/include/linux/platform_data/ntc_thermistor.h @@ -21,6 +21,8 @@ #ifndef _LINUX_NTC_H #define _LINUX_NTC_H +struct iio_channel; + enum ntc_thermistor_type { TYPE_NCPXXWB473, TYPE_NCPXXWL333, @@ -39,13 +41,17 @@ struct ntc_thermistor_platform_data { * described at Documentation/hwmon/ntc_thermistor * * pullup/down_ohm: 0 for infinite / not-connected + * + * chan: iio_channel pointer to communicate with the ADC which the + * thermistor is using for conversion of the analog values. */ - int (*read_uV)(void); - unsigned int pullup_uV; + int (*read_uv)(struct ntc_thermistor_platform_data *); + unsigned int pullup_uv; unsigned int pullup_ohm; unsigned int pulldown_ohm; enum { NTC_CONNECTED_POSITIVE, NTC_CONNECTED_GROUND } connect; + struct iio_channel *chan; int (*read_ohm)(void); }; diff --git a/include/linux/platform_data/omap-abe-twl6040.h b/include/linux/platform_data/omap-abe-twl6040.h deleted file mode 100644 index 5d298ac10fc2..000000000000 --- a/include/linux/platform_data/omap-abe-twl6040.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * omap-abe-twl6040.h - ASoC machine driver OMAP4+ devices, header. - * - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com - * All rights reserved. - * - * Author: Peter Ujfalusi <peter.ujfalusi@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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef _OMAP_ABE_TWL6040_H_ -#define _OMAP_ABE_TWL6040_H_ - -/* To select if only one channel is connected in a stereo port */ -#define ABE_TWL6040_LEFT (1 << 0) -#define ABE_TWL6040_RIGHT (1 << 1) - -struct omap_abe_twl6040_data { - char *card_name; - /* Feature flags for connected audio pins */ - u8 has_hs; - u8 has_hf; - bool has_ep; - u8 has_aux; - u8 has_vibra; - bool has_dmic; - bool has_hsmic; - bool has_mainmic; - bool has_submic; - u8 has_afm; - /* Other features */ - bool jack_detection; /* board can detect jack events */ - int mclk_freq; /* MCLK frequency speed for twl6040 */ -}; - -#endif /* _OMAP_ABE_TWL6040_H_ */ diff --git a/include/linux/platform_data/omap_ocp2scp.h b/include/linux/platform_data/omap_ocp2scp.h deleted file mode 100644 index 5c6c3939355f..000000000000 --- a/include/linux/platform_data/omap_ocp2scp.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * omap_ocp2scp.h -- ocp2scp header file - * - * 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 as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Author: Kishon Vijay Abraham I <kishon@ti.com> - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __DRIVERS_OMAP_OCP2SCP_H -#define __DRIVERS_OMAP_OCP2SCP_H - -struct omap_ocp2scp_dev { - const char *drv_name; - struct resource *res; -}; - -struct omap_ocp2scp_platform_data { - int dev_cnt; - struct omap_ocp2scp_dev **devices; -}; -#endif /* __DRIVERS_OMAP_OCP2SCP_H */ diff --git a/include/linux/i2c/pca953x.h b/include/linux/platform_data/pca953x.h index 3c98dd4f901f..3c98dd4f901f 100644 --- a/include/linux/i2c/pca953x.h +++ b/include/linux/platform_data/pca953x.h diff --git a/include/linux/platform_data/pinctrl-adi2.h b/include/linux/platform_data/pinctrl-adi2.h new file mode 100644 index 000000000000..8f91300617ec --- /dev/null +++ b/include/linux/platform_data/pinctrl-adi2.h @@ -0,0 +1,40 @@ +/* + * Pinctrl Driver for ADI GPIO2 controller + * + * Copyright 2007-2013 Analog Devices Inc. + * + * Licensed under the GPLv2 or later + */ + + +#ifndef PINCTRL_ADI2_H +#define PINCTRL_ADI2_H + +#include <linux/io.h> +#include <linux/platform_device.h> + +/** + * struct adi_pinctrl_gpio_platform_data - Pinctrl gpio platform data + * for ADI GPIO2 device. + * + * @port_gpio_base: Optional global GPIO index of the GPIO bank. + * 0 means driver decides. + * @port_pin_base: Pin index of the pin controller device. + * @port_width: PIN number of the GPIO bank device + * @pint_id: GPIO PINT device id that this GPIO bank should map to. + * @pint_assign: The 32-bit GPIO PINT registers can be divided into 2 parts. A + * GPIO bank can be mapped into either low 16 bits[0] or high 16 + * bits[1] of each PINT register. + * @pint_map: GIOP bank mapping code in PINT device + */ +struct adi_pinctrl_gpio_platform_data { + unsigned int port_gpio_base; + unsigned int port_pin_base; + unsigned int port_width; + u8 pinctrl_id; + u8 pint_id; + bool pint_assign; + u8 pint_map; +}; + +#endif diff --git a/include/linux/platform_data/pinctrl-coh901.h b/include/linux/platform_data/pinctrl-coh901.h deleted file mode 100644 index dfbc65d10484..000000000000 --- a/include/linux/platform_data/pinctrl-coh901.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2007-2012 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * GPIO block resgister definitions and inline macros for - * U300 GPIO COH 901 335 or COH 901 571/3 - * Author: Linus Walleij <linus.walleij@stericsson.com> - */ - -#ifndef __MACH_U300_GPIO_U300_H -#define __MACH_U300_GPIO_U300_H - -/** - * struct u300_gpio_platform - U300 GPIO platform data - * @ports: number of GPIO block ports - * @gpio_base: first GPIO number for this block (use a free range) - */ -struct u300_gpio_platform { - u8 ports; - int gpio_base; -}; - -#endif /* __MACH_U300_GPIO_U300_H */ diff --git a/include/linux/platform_data/pinctrl-nomadik.h b/include/linux/platform_data/pinctrl-nomadik.h index f73b2f0c55b7..abf5bed84df3 100644 --- a/include/linux/platform_data/pinctrl-nomadik.h +++ b/include/linux/platform_data/pinctrl-nomadik.h @@ -226,30 +226,6 @@ enum nmk_gpio_slpm { NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE, }; -/* Older deprecated pin config API that should go away soon */ -extern int nmk_config_pin(pin_cfg_t cfg, bool sleep); -extern int nmk_config_pins(pin_cfg_t *cfgs, int num); -extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num); -extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode); -extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull); -#ifdef CONFIG_PINCTRL_NOMADIK -extern int nmk_gpio_set_mode(int gpio, int gpio_mode); -#else -static inline int nmk_gpio_set_mode(int gpio, int gpio_mode) -{ - return -ENODEV; -} -#endif -extern int nmk_gpio_get_mode(int gpio); - -extern void nmk_gpio_wakeups_suspend(void); -extern void nmk_gpio_wakeups_resume(void); - -extern void nmk_gpio_clocks_enable(void); -extern void nmk_gpio_clocks_disable(void); - -extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up); - /* * Platform data to register a block: only the initial gpio/irq number. */ diff --git a/include/linux/platform_data/pwm-renesas-tpu.h b/include/linux/platform_data/pwm-renesas-tpu.h new file mode 100644 index 000000000000..a7220b10ddab --- /dev/null +++ b/include/linux/platform_data/pwm-renesas-tpu.h @@ -0,0 +1,16 @@ +#ifndef __PWM_RENESAS_TPU_H__ +#define __PWM_RENESAS_TPU_H__ + +#include <linux/pwm.h> + +#define TPU_CHANNEL_MAX 4 + +struct tpu_pwm_channel_data { + enum pwm_polarity polarity; +}; + +struct tpu_pwm_platform_data { + struct tpu_pwm_channel_data channels[TPU_CHANNEL_MAX]; +}; + +#endif /* __PWM_RENESAS_TPU_H__ */ diff --git a/include/linux/platform_data/rcar-du.h b/include/linux/platform_data/rcar-du.h new file mode 100644 index 000000000000..1a2e9901a22e --- /dev/null +++ b/include/linux/platform_data/rcar-du.h @@ -0,0 +1,74 @@ +/* + * rcar_du.h -- R-Car Display Unit DRM driver + * + * Copyright (C) 2013 Renesas Corporation + * + * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.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 __RCAR_DU_H__ +#define __RCAR_DU_H__ + +#include <drm/drm_mode.h> + +enum rcar_du_output { + RCAR_DU_OUTPUT_DPAD0, + RCAR_DU_OUTPUT_DPAD1, + RCAR_DU_OUTPUT_LVDS0, + RCAR_DU_OUTPUT_LVDS1, + RCAR_DU_OUTPUT_TCON, + RCAR_DU_OUTPUT_MAX, +}; + +enum rcar_du_encoder_type { + RCAR_DU_ENCODER_UNUSED = 0, + RCAR_DU_ENCODER_NONE, + RCAR_DU_ENCODER_VGA, + RCAR_DU_ENCODER_LVDS, +}; + +struct rcar_du_panel_data { + unsigned int width_mm; /* Panel width in mm */ + unsigned int height_mm; /* Panel height in mm */ + struct drm_mode_modeinfo mode; +}; + +struct rcar_du_connector_lvds_data { + struct rcar_du_panel_data panel; +}; + +struct rcar_du_connector_vga_data { + /* TODO: Add DDC information for EDID retrieval */ +}; + +/* + * struct rcar_du_encoder_data - Encoder platform data + * @type: the encoder type (RCAR_DU_ENCODER_*) + * @output: the DU output the connector is connected to (RCAR_DU_OUTPUT_*) + * @connector.lvds: platform data for LVDS connectors + * @connector.vga: platform data for VGA connectors + * + * Encoder platform data describes an on-board encoder, its associated DU SoC + * output, and the connector. + */ +struct rcar_du_encoder_data { + enum rcar_du_encoder_type type; + enum rcar_du_output output; + + union { + struct rcar_du_connector_lvds_data lvds; + struct rcar_du_connector_vga_data vga; + } connector; +}; + +struct rcar_du_platform_data { + struct rcar_du_encoder_data *encoders; + unsigned int num_encoders; +}; + +#endif /* __RCAR_DU_H__ */ diff --git a/include/linux/platform_data/remoteproc-omap.h b/include/linux/platform_data/remoteproc-omap.h index 3c1c6444ec4b..bfbd12b41162 100644 --- a/include/linux/platform_data/remoteproc-omap.h +++ b/include/linux/platform_data/remoteproc-omap.h @@ -50,7 +50,7 @@ void __init omap_rproc_reserve_cma(void); #else -void __init omap_rproc_reserve_cma(void) +static inline void __init omap_rproc_reserve_cma(void) { } diff --git a/include/linux/platform_data/serial-omap.h b/include/linux/platform_data/serial-omap.h index ff9b0aab5281..c860c1b314c0 100644 --- a/include/linux/platform_data/serial-omap.h +++ b/include/linux/platform_data/serial-omap.h @@ -43,8 +43,6 @@ struct omap_uart_port_info { int DTR_present; int (*get_context_loss_count)(struct device *); - void (*set_forceidle)(struct device *); - void (*set_noidle)(struct device *); void (*enable_wakeup)(struct device *, bool); }; diff --git a/include/linux/platform_data/serial-sccnxp.h b/include/linux/platform_data/serial-sccnxp.h index 215574d1e81d..af0c8c3b89ae 100644 --- a/include/linux/platform_data/serial-sccnxp.h +++ b/include/linux/platform_data/serial-sccnxp.h @@ -60,7 +60,6 @@ * }; * * static struct sccnxp_pdata sc2892_info = { - * .frequency = 3686400, * .mctrl_cfg[0] = MCTRL_SIG(DIR_OP, LINE_OP0), * .mctrl_cfg[1] = MCTRL_SIG(DIR_OP, LINE_OP1), * }; @@ -78,18 +77,12 @@ /* SCCNXP platform data structure */ struct sccnxp_pdata { - /* Frequency (extrenal clock or crystal) */ - int frequency; /* Shift for A0 line */ const u8 reg_shift; /* Modem control lines configuration */ const u32 mctrl_cfg[SCCNXP_MAX_UARTS]; /* Timer value for polling mode (usecs) */ const unsigned int poll_time_us; - /* Called during startup */ - void (*init)(void); - /* Called before finish */ - void (*exit)(void); }; #endif diff --git a/include/linux/platform_data/si5351.h b/include/linux/platform_data/si5351.h new file mode 100644 index 000000000000..54334393ab92 --- /dev/null +++ b/include/linux/platform_data/si5351.h @@ -0,0 +1,132 @@ +/* + * Si5351A/B/C programmable clock generator platform_data. + */ + +#ifndef __LINUX_PLATFORM_DATA_SI5351_H__ +#define __LINUX_PLATFORM_DATA_SI5351_H__ + +struct clk; + +/** + * enum si5351_variant - SiLabs Si5351 chip variant + * @SI5351_VARIANT_A: Si5351A (8 output clocks, XTAL input) + * @SI5351_VARIANT_A3: Si5351A MSOP10 (3 output clocks, XTAL input) + * @SI5351_VARIANT_B: Si5351B (8 output clocks, XTAL/VXCO input) + * @SI5351_VARIANT_C: Si5351C (8 output clocks, XTAL/CLKIN input) + */ +enum si5351_variant { + SI5351_VARIANT_A = 1, + SI5351_VARIANT_A3 = 2, + SI5351_VARIANT_B = 3, + SI5351_VARIANT_C = 4, +}; + +/** + * enum si5351_pll_src - Si5351 pll clock source + * @SI5351_PLL_SRC_DEFAULT: default, do not change eeprom config + * @SI5351_PLL_SRC_XTAL: pll source clock is XTAL input + * @SI5351_PLL_SRC_CLKIN: pll source clock is CLKIN input (Si5351C only) + */ +enum si5351_pll_src { + SI5351_PLL_SRC_DEFAULT = 0, + SI5351_PLL_SRC_XTAL = 1, + SI5351_PLL_SRC_CLKIN = 2, +}; + +/** + * enum si5351_multisynth_src - Si5351 multisynth clock source + * @SI5351_MULTISYNTH_SRC_DEFAULT: default, do not change eeprom config + * @SI5351_MULTISYNTH_SRC_VCO0: multisynth source clock is VCO0 + * @SI5351_MULTISYNTH_SRC_VCO1: multisynth source clock is VCO1/VXCO + */ +enum si5351_multisynth_src { + SI5351_MULTISYNTH_SRC_DEFAULT = 0, + SI5351_MULTISYNTH_SRC_VCO0 = 1, + SI5351_MULTISYNTH_SRC_VCO1 = 2, +}; + +/** + * enum si5351_clkout_src - Si5351 clock output clock source + * @SI5351_CLKOUT_SRC_DEFAULT: default, do not change eeprom config + * @SI5351_CLKOUT_SRC_MSYNTH_N: clkout N source clock is multisynth N + * @SI5351_CLKOUT_SRC_MSYNTH_0_4: clkout N source clock is multisynth 0 (N<4) + * or 4 (N>=4) + * @SI5351_CLKOUT_SRC_XTAL: clkout N source clock is XTAL + * @SI5351_CLKOUT_SRC_CLKIN: clkout N source clock is CLKIN (Si5351C only) + */ +enum si5351_clkout_src { + SI5351_CLKOUT_SRC_DEFAULT = 0, + SI5351_CLKOUT_SRC_MSYNTH_N = 1, + SI5351_CLKOUT_SRC_MSYNTH_0_4 = 2, + SI5351_CLKOUT_SRC_XTAL = 3, + SI5351_CLKOUT_SRC_CLKIN = 4, +}; + +/** + * enum si5351_drive_strength - Si5351 clock output drive strength + * @SI5351_DRIVE_DEFAULT: default, do not change eeprom config + * @SI5351_DRIVE_2MA: 2mA clock output drive strength + * @SI5351_DRIVE_4MA: 4mA clock output drive strength + * @SI5351_DRIVE_6MA: 6mA clock output drive strength + * @SI5351_DRIVE_8MA: 8mA clock output drive strength + */ +enum si5351_drive_strength { + SI5351_DRIVE_DEFAULT = 0, + SI5351_DRIVE_2MA = 2, + SI5351_DRIVE_4MA = 4, + SI5351_DRIVE_6MA = 6, + SI5351_DRIVE_8MA = 8, +}; + +/** + * enum si5351_disable_state - Si5351 clock output disable state + * @SI5351_DISABLE_DEFAULT: default, do not change eeprom config + * @SI5351_DISABLE_LOW: CLKx is set to a LOW state when disabled + * @SI5351_DISABLE_HIGH: CLKx is set to a HIGH state when disabled + * @SI5351_DISABLE_FLOATING: CLKx is set to a FLOATING state when + * disabled + * @SI5351_DISABLE_NEVER: CLKx is NEVER disabled + */ +enum si5351_disable_state { + SI5351_DISABLE_DEFAULT = 0, + SI5351_DISABLE_LOW, + SI5351_DISABLE_HIGH, + SI5351_DISABLE_FLOATING, + SI5351_DISABLE_NEVER, +}; + +/** + * struct si5351_clkout_config - Si5351 clock output configuration + * @clkout: clkout number + * @multisynth_src: multisynth source clock + * @clkout_src: clkout source clock + * @pll_master: if true, clkout can also change pll rate + * @drive: output drive strength + * @rate: initial clkout rate, or default if 0 + */ +struct si5351_clkout_config { + enum si5351_multisynth_src multisynth_src; + enum si5351_clkout_src clkout_src; + enum si5351_drive_strength drive; + enum si5351_disable_state disable_state; + bool pll_master; + unsigned long rate; +}; + +/** + * struct si5351_platform_data - Platform data for the Si5351 clock driver + * @variant: Si5351 chip variant + * @clk_xtal: xtal input clock + * @clk_clkin: clkin input clock + * @pll_src: array of pll source clock setting + * @clkout: array of clkout configuration + */ +struct si5351_platform_data { + enum si5351_variant variant; + struct clk *clk_xtal; + struct clk *clk_clkin; + enum si5351_pll_src pll_src[2]; + struct si5351_clkout_config clkout[8]; +}; + +#endif diff --git a/include/linux/platform_data/simplefb.h b/include/linux/platform_data/simplefb.h new file mode 100644 index 000000000000..077303cedbf4 --- /dev/null +++ b/include/linux/platform_data/simplefb.h @@ -0,0 +1,64 @@ +/* + * simplefb.h - Simple Framebuffer Device + * + * Copyright (C) 2013 David Herrmann <dh.herrmann@gmail.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 __PLATFORM_DATA_SIMPLEFB_H__ +#define __PLATFORM_DATA_SIMPLEFB_H__ + +#include <drm/drm_fourcc.h> +#include <linux/fb.h> +#include <linux/kernel.h> + +/* format array, use it to initialize a "struct simplefb_format" array */ +#define SIMPLEFB_FORMATS \ +{ \ + { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0}, DRM_FORMAT_RGB565 }, \ + { "x1r5g5b5", 16, {10, 5}, {5, 5}, {0, 5}, {0, 0}, DRM_FORMAT_XRGB1555 }, \ + { "a1r5g5b5", 16, {10, 5}, {5, 5}, {0, 5}, {15, 1}, DRM_FORMAT_ARGB1555 }, \ + { "r8g8b8", 24, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_RGB888 }, \ + { "x8r8g8b8", 32, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_XRGB8888 }, \ + { "a8r8g8b8", 32, {16, 8}, {8, 8}, {0, 8}, {24, 8}, DRM_FORMAT_ARGB8888 }, \ + { "a8b8g8r8", 32, {0, 8}, {8, 8}, {16, 8}, {24, 8}, DRM_FORMAT_ABGR8888 }, \ + { "x2r10g10b10", 32, {20, 10}, {10, 10}, {0, 10}, {0, 0}, DRM_FORMAT_XRGB2101010 }, \ + { "a2r10g10b10", 32, {20, 10}, {10, 10}, {0, 10}, {30, 2}, DRM_FORMAT_ARGB2101010 }, \ +} + +/* + * Data-Format for Simple-Framebuffers + * @name: unique 0-terminated name that can be used to identify the mode + * @red,green,blue: Offsets and sizes of the single RGB parts + * @transp: Offset and size of the alpha bits. length=0 means no alpha + * @fourcc: 32bit DRM four-CC code (see drm_fourcc.h) + */ +struct simplefb_format { + const char *name; + u32 bits_per_pixel; + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; + u32 fourcc; +}; + +/* + * Simple-Framebuffer description + * If the arch-boot code creates simple-framebuffers without DT support, it + * can pass the width, height, stride and format via this platform-data object. + * The framebuffer location must be given as IORESOURCE_MEM resource. + * @format must be a format as described in "struct simplefb_format" above. + */ +struct simplefb_platform_data { + u32 width; + u32 height; + u32 stride; + const char *format; +}; + +#endif /* __PLATFORM_DATA_SIMPLEFB_H__ */ diff --git a/include/linux/platform_data/spi-davinci.h b/include/linux/platform_data/spi-davinci.h index 7af305b37868..8dc2fa47a2aa 100644 --- a/include/linux/platform_data/spi-davinci.h +++ b/include/linux/platform_data/spi-davinci.h @@ -19,7 +19,7 @@ #ifndef __ARCH_ARM_DAVINCI_SPI_H #define __ARCH_ARM_DAVINCI_SPI_H -#include <mach/edma.h> +#include <linux/platform_data/edma.h> #define SPI_INTERN_CS 0xFF diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h index ceba18d23a5a..8447f634c7f5 100644 --- a/include/linux/platform_data/spi-s3c64xx.h +++ b/include/linux/platform_data/spi-s3c64xx.h @@ -11,6 +11,8 @@ #ifndef __S3C64XX_PLAT_SPI_H #define __S3C64XX_PLAT_SPI_H +#include <linux/dmaengine.h> + struct platform_device; /** @@ -38,6 +40,7 @@ struct s3c64xx_spi_info { int src_clk_nr; int num_cs; int (*cfg_gpio)(void); + dma_filter_fn filter; }; /** diff --git a/include/linux/platform_data/ssm2518.h b/include/linux/platform_data/ssm2518.h new file mode 100644 index 000000000000..9a8e3ea287e3 --- /dev/null +++ b/include/linux/platform_data/ssm2518.h @@ -0,0 +1,22 @@ +/* + * SSM2518 amplifier audio driver + * + * Copyright 2013 Analog Devices Inc. + * Author: Lars-Peter Clausen <lars@metafoo.de> + * + * Licensed under the GPL-2. + */ + +#ifndef __LINUX_PLATFORM_DATA_SSM2518_H__ +#define __LINUX_PLATFORM_DATA_SSM2518_H__ + +/** + * struct ssm2518_platform_data - Platform data for the ssm2518 driver + * @enable_gpio: GPIO connected to the nSD pin. Set to -1 if the nSD pin is + * hardwired. + */ +struct ssm2518_platform_data { + int enable_gpio; +}; + +#endif diff --git a/include/linux/platform_data/st1232_pdata.h b/include/linux/platform_data/st1232_pdata.h new file mode 100644 index 000000000000..cac3e7b4c454 --- /dev/null +++ b/include/linux/platform_data/st1232_pdata.h @@ -0,0 +1,13 @@ +#ifndef _LINUX_ST1232_PDATA_H +#define _LINUX_ST1232_PDATA_H + +/* + * Optional platform data + * + * Use this if you want the driver to drive the reset pin. + */ +struct st1232_pdata { + int reset_gpio; +}; + +#endif diff --git a/include/linux/platform_data/st_sensors_pdata.h b/include/linux/platform_data/st_sensors_pdata.h new file mode 100644 index 000000000000..753839187ba0 --- /dev/null +++ b/include/linux/platform_data/st_sensors_pdata.h @@ -0,0 +1,24 @@ +/* + * STMicroelectronics sensors platform-data driver + * + * Copyright 2013 STMicroelectronics Inc. + * + * Denis Ciocca <denis.ciocca@st.com> + * + * Licensed under the GPL-2. + */ + +#ifndef ST_SENSORS_PDATA_H +#define ST_SENSORS_PDATA_H + +/** + * struct st_sensors_platform_data - Platform data for the ST sensors + * @drdy_int_pin: Redirect DRDY on pin 1 (1) or pin 2 (2). + * Available only for accelerometer and pressure sensors. + * Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet). + */ +struct st_sensors_platform_data { + u8 drdy_int_pin; +}; + +#endif /* ST_SENSORS_PDATA_H */ diff --git a/include/linux/platform_data/tegra_usb.h b/include/linux/platform_data/tegra_usb.h deleted file mode 100644 index 66c673fef408..000000000000 --- a/include/linux/platform_data/tegra_usb.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _TEGRA_USB_H_ -#define _TEGRA_USB_H_ - -enum tegra_usb_operating_modes { - TEGRA_USB_DEVICE, - TEGRA_USB_HOST, - TEGRA_USB_OTG, -}; - -struct tegra_ehci_platform_data { - enum tegra_usb_operating_modes operating_mode; - /* power down the phy on bus suspend */ - int power_down_on_bus_suspend; - void *phy_config; - int vbus_gpio; -}; - -#endif /* _TEGRA_USB_H_ */ diff --git a/include/linux/platform_data/ti_am335x_adc.h b/include/linux/platform_data/ti_am335x_adc.h deleted file mode 100644 index e41d5834cb84..000000000000 --- a/include/linux/platform_data/ti_am335x_adc.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __LINUX_TI_AM335X_ADC_H -#define __LINUX_TI_AM335X_ADC_H - -/** - * struct adc_data ADC Input information - * @adc_channels: Number of analog inputs - * available for ADC. - */ - -struct adc_data { - unsigned int adc_channels; -}; - -#endif diff --git a/include/linux/platform_data/usb-musb-ux500.h b/include/linux/platform_data/usb-musb-ux500.h index 4c1cc50a595a..dd9c83ac7de0 100644 --- a/include/linux/platform_data/usb-musb-ux500.h +++ b/include/linux/platform_data/usb-musb-ux500.h @@ -9,14 +9,11 @@ #include <linux/dmaengine.h> -#define UX500_MUSB_DMA_NUM_RX_CHANNELS 8 -#define UX500_MUSB_DMA_NUM_TX_CHANNELS 8 +#define UX500_MUSB_DMA_NUM_RX_TX_CHANNELS 8 struct ux500_musb_board_data { void **dma_rx_param_array; void **dma_tx_param_array; - u32 num_rx_channels; - u32 num_tx_channels; bool (*dma_filter)(struct dma_chan *chan, void *filter_param); }; diff --git a/include/linux/platform_data/usb-exynos.h b/include/linux/platform_data/usb-ohci-exynos.h index c256c595be5e..c256c595be5e 100644 --- a/include/linux/platform_data/usb-exynos.h +++ b/include/linux/platform_data/usb-ohci-exynos.h diff --git a/include/linux/platform_data/usb-rcar-phy.h b/include/linux/platform_data/usb-rcar-phy.h new file mode 100644 index 000000000000..8ec6964a32a5 --- /dev/null +++ b/include/linux/platform_data/usb-rcar-phy.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Cogent Embedded, Inc. + * + * 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 __USB_RCAR_PHY_H +#define __USB_RCAR_PHY_H + +#include <linux/types.h> + +struct rcar_phy_platform_data { + bool ferrite_bead:1; /* (R8A7778 only) */ + + bool port1_func:1; /* true: port 1 used by function, false: host */ + unsigned penc1:1; /* Output of the PENC1 pin in function mode */ + struct { /* Overcurrent pin control for ports 0..2 */ + bool select_3_3v:1; /* true: USB_OVCn pin, false: OVCn pin */ + /* Set to false on port 1 in function mode */ + bool active_high:1; /* true: active high, false: active low */ + /* Set to true on port 1 in function mode */ + } ovc_pin[3]; /* (R8A7778 only has 2 ports) */ +}; + +#endif /* __USB_RCAR_PHY_H */ diff --git a/include/linux/platform_data/usb3503.h b/include/linux/platform_data/usb3503.h index 85dcc709f7e9..1d1b6ef871f6 100644 --- a/include/linux/platform_data/usb3503.h +++ b/include/linux/platform_data/usb3503.h @@ -3,6 +3,10 @@ #define USB3503_I2C_NAME "usb3503" +#define USB3503_OFF_PORT1 (1 << 1) +#define USB3503_OFF_PORT2 (1 << 2) +#define USB3503_OFF_PORT3 (1 << 3) + enum usb3503_mode { USB3503_MODE_UNKNOWN, USB3503_MODE_HUB, @@ -11,6 +15,7 @@ enum usb3503_mode { struct usb3503_platform_data { enum usb3503_mode initial_mode; + u8 port_off_mask; int gpio_intn; int gpio_connect; int gpio_reset; diff --git a/include/linux/platform_data/video-vt8500lcdfb.h b/include/linux/platform_data/video-vt8500lcdfb.h deleted file mode 100644 index 7f399c370fe0..000000000000 --- a/include/linux/platform_data/video-vt8500lcdfb.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * VT8500/WM8505 Frame Buffer platform data definitions - * - * Copyright (C) 2010 Ed Spiridonov <edo.rus@gmail.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _VT8500FB_H -#define _VT8500FB_H - -#include <linux/fb.h> - -struct vt8500fb_platform_data { - struct fb_videomode mode; - u32 xres_virtual; - u32 yres_virtual; - u32 bpp; - unsigned long video_mem_phys; - void *video_mem_virt; - unsigned long video_mem_len; -}; - -#endif /* _VT8500FB_H */ diff --git a/include/linux/platform_data/video_s3c.h b/include/linux/platform_data/video_s3c.h new file mode 100644 index 000000000000..48883995f47f --- /dev/null +++ b/include/linux/platform_data/video_s3c.h @@ -0,0 +1,54 @@ +#ifndef __PLATFORM_DATA_VIDEO_S3C +#define __PLATFORM_DATA_VIDEO_S3C + +/* S3C_FB_MAX_WIN + * Set to the maximum number of windows that any of the supported hardware + * can use. Since the platform data uses this for an array size, having it + * set to the maximum of any version of the hardware can do is safe. + */ +#define S3C_FB_MAX_WIN (5) + +/** + * struct s3c_fb_pd_win - per window setup data + * @xres : The window X size. + * @yres : The window Y size. + * @virtual_x: The virtual X size. + * @virtual_y: The virtual Y size. + */ +struct s3c_fb_pd_win { + unsigned short default_bpp; + unsigned short max_bpp; + unsigned short xres; + unsigned short yres; + unsigned short virtual_x; + unsigned short virtual_y; +}; + +/** + * struct s3c_fb_platdata - S3C driver platform specific information + * @setup_gpio: Setup the external GPIO pins to the right state to transfer + * the data from the display system to the connected display + * device. + * @vidcon0: The base vidcon0 values to control the panel data format. + * @vidcon1: The base vidcon1 values to control the panel data output. + * @vtiming: Video timing when connected to a RGB type panel. + * @win: The setup data for each hardware window, or NULL for unused. + * @display_mode: The LCD output display mode. + * + * The platform data supplies the video driver with all the information + * it requires to work with the display(s) attached to the machine. It + * controls the initial mode, the number of display windows (0 is always + * the base framebuffer) that are initialised etc. + * + */ +struct s3c_fb_platdata { + void (*setup_gpio)(void); + + struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN]; + struct fb_videomode *vtiming; + + u32 vidcon0; + u32 vidcon1; +}; + +#endif diff --git a/include/linux/platform_data/vsp1.h b/include/linux/platform_data/vsp1.h new file mode 100644 index 000000000000..a73a456d7f11 --- /dev/null +++ b/include/linux/platform_data/vsp1.h @@ -0,0 +1,25 @@ +/* + * vsp1.h -- R-Car VSP1 Platform Data + * + * Copyright (C) 2013 Renesas Corporation + * + * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.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 __PLATFORM_VSP1_H__ +#define __PLATFORM_VSP1_H__ + +#define VSP1_HAS_LIF (1 << 0) + +struct vsp1_platform_data { + unsigned int features; + unsigned int rpf_count; + unsigned int uds_count; + unsigned int wpf_count; +}; + +#endif /* __PLATFORM_VSP1_H__ */ diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index c082c71f7225..16f6654082dd 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -20,12 +20,12 @@ struct mfd_cell; struct platform_device { - const char * name; + const char *name; int id; bool id_auto; struct device dev; u32 num_resources; - struct resource * resource; + struct resource *resource; const struct platform_device_id *id_entry; @@ -47,9 +47,12 @@ extern struct bus_type platform_bus_type; extern struct device platform_bus; extern void arch_setup_pdev_archdata(struct platform_device *); -extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int); +extern struct resource *platform_get_resource(struct platform_device *, + unsigned int, unsigned int); extern int platform_get_irq(struct platform_device *, unsigned int); -extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, const char *); +extern struct resource *platform_get_resource_byname(struct platform_device *, + unsigned int, + const char *); extern int platform_get_irq_byname(struct platform_device *, const char *); extern int platform_add_devices(struct platform_device **, int); @@ -161,7 +164,8 @@ extern struct platform_device *platform_device_alloc(const char *name, int id); extern int platform_device_add_resources(struct platform_device *pdev, const struct resource *res, unsigned int num); -extern int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size); +extern int platform_device_add_data(struct platform_device *pdev, + const void *data, size_t size); extern int platform_device_add(struct platform_device *pdev); extern void platform_device_del(struct platform_device *pdev); extern void platform_device_put(struct platform_device *pdev); @@ -174,9 +178,19 @@ struct platform_driver { int (*resume)(struct platform_device *); struct device_driver driver; const struct platform_device_id *id_table; + bool prevent_deferred_probe; }; -extern int platform_driver_register(struct platform_driver *); +#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \ + driver)) + +/* + * use a macro to avoid include chaining to get THIS_MODULE + */ +#define platform_driver_register(drv) \ + __platform_driver_register(drv, THIS_MODULE) +extern int __platform_driver_register(struct platform_driver *, + struct module *); extern void platform_driver_unregister(struct platform_driver *); /* non-hotpluggable platform devices may use this so that probe() and @@ -190,7 +204,8 @@ static inline void *platform_get_drvdata(const struct platform_device *pdev) return dev_get_drvdata(&pdev->dev); } -static inline void platform_set_drvdata(struct platform_device *pdev, void *data) +static inline void platform_set_drvdata(struct platform_device *pdev, + void *data) { dev_set_drvdata(&pdev->dev, data); } @@ -222,10 +237,10 @@ static void __exit __platform_driver##_exit(void) \ } \ module_exit(__platform_driver##_exit); -extern struct platform_device *platform_create_bundle(struct platform_driver *driver, - int (*probe)(struct platform_device *), - struct resource *res, unsigned int n_res, - const void *data, size_t size); +extern struct platform_device *platform_create_bundle( + struct platform_driver *driver, int (*probe)(struct platform_device *), + struct resource *res, unsigned int n_res, + const void *data, size_t size); /* early platform driver interface */ struct early_platform_driver { diff --git a/include/linux/pm.h b/include/linux/pm.h index e5d7230332a4..a224c7f5c377 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -34,6 +34,19 @@ extern void (*pm_power_off)(void); extern void (*pm_power_off_prepare)(void); +struct device; /* we have a circular dep with device.h */ +#ifdef CONFIG_VT_CONSOLE_SLEEP +extern void pm_vt_switch_required(struct device *dev, bool required); +extern void pm_vt_switch_unregister(struct device *dev); +#else +static inline void pm_vt_switch_required(struct device *dev, bool required) +{ +} +static inline void pm_vt_switch_unregister(struct device *dev) +{ +} +#endif /* CONFIG_VT_CONSOLE_SLEEP */ + /* * Device power management */ diff --git a/include/linux/pm2301_charger.h b/include/linux/pm2301_charger.h index fc3f026922ae..85c16defe11a 100644 --- a/include/linux/pm2301_charger.h +++ b/include/linux/pm2301_charger.h @@ -48,7 +48,7 @@ struct pm2xxx_charger_platform_data { size_t num_supplicants; int i2c_bus; const char *label; - int irq_number; + int gpio_irq_number; unsigned int lpn_gpio; int irq_type; }; diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 7d7e09efff9b..6fa7cea25da9 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -37,7 +37,6 @@ extern void pm_runtime_enable(struct device *dev); extern void __pm_runtime_disable(struct device *dev, bool check_resume); extern void pm_runtime_allow(struct device *dev); extern void pm_runtime_forbid(struct device *dev); -extern int pm_generic_runtime_idle(struct device *dev); extern int pm_generic_runtime_suspend(struct device *dev); extern int pm_generic_runtime_resume(struct device *dev); extern void pm_runtime_no_callbacks(struct device *dev); @@ -143,7 +142,6 @@ static inline bool pm_runtime_active(struct device *dev) { return true; } static inline bool pm_runtime_status_suspended(struct device *dev) { return false; } static inline bool pm_runtime_enabled(struct device *dev) { return false; } -static inline int pm_generic_runtime_idle(struct device *dev) { return 0; } static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; } static inline int pm_generic_runtime_resume(struct device *dev) { return 0; } static inline void pm_runtime_no_callbacks(struct device *dev) {} diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 569781faa504..a0f70808d7f4 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -36,8 +36,8 @@ * @last_time: Monotonic clock when the wakeup source's was touched last time. * @prevent_sleep_time: Total time this source has been preventing autosleep. * @event_count: Number of signaled wakeup events. - * @active_count: Number of times the wakeup sorce was activated. - * @relax_count: Number of times the wakeup sorce was deactivated. + * @active_count: Number of times the wakeup source was activated. + * @relax_count: Number of times the wakeup source was deactivated. * @expire_count: Number of times the wakeup source's timeout has expired. * @wakeup_count: Number of times the wakeup source might abort suspend. * @active: Status of the wakeup source. diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 042058fdb0af..907f3fd191ac 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -7,14 +7,20 @@ #include <linux/timex.h> #include <linux/alarmtimer.h> -union cpu_time_count { - cputime_t cpu; - unsigned long long sched; -}; + +static inline unsigned long long cputime_to_expires(cputime_t expires) +{ + return (__force unsigned long long)expires; +} + +static inline cputime_t expires_to_cputime(unsigned long long expires) +{ + return (__force cputime_t)expires; +} struct cpu_timer_list { struct list_head entry; - union cpu_time_count expires, incr; + unsigned long long expires, incr; struct task_struct *task; int firing; }; @@ -55,6 +61,7 @@ struct cpu_timer_list { /* POSIX.1b interval timer structure. */ struct k_itimer { struct list_head list; /* free/ allocate list */ + struct hlist_node t_hash; spinlock_t it_lock; clockid_t it_clock; /* which timer type */ timer_t it_id; /* timer id */ @@ -122,6 +129,8 @@ void run_posix_cpu_timers(struct task_struct *task); void posix_cpu_timers_exit(struct task_struct *task); void posix_cpu_timers_exit_group(struct task_struct *task); +bool posix_cpu_timers_can_stop_tick(struct task_struct *tsk); + void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx, cputime_t *newval, cputime_t *oldval); diff --git a/include/linux/power/ab8500.h b/include/linux/power/ab8500.h new file mode 100644 index 000000000000..cdbb6c2a8c51 --- /dev/null +++ b/include/linux/power/ab8500.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) ST-Ericsson 2013 + * Author: Hongbo Zhang <hongbo.zhang@linaro.com> + * License terms: GNU General Public License v2 + */ + +#ifndef PWR_AB8500_H +#define PWR_AB8500_H + +extern const struct abx500_res_to_temp ab8500_temp_tbl_a_thermistor[]; +extern const int ab8500_temp_tbl_a_size; + +extern const struct abx500_res_to_temp ab8500_temp_tbl_b_thermistor[]; +extern const int ab8500_temp_tbl_b_size; + +#endif /* PWR_AB8500_H */ diff --git a/include/linux/power/bq24190_charger.h b/include/linux/power/bq24190_charger.h new file mode 100644 index 000000000000..9f0283721cbc --- /dev/null +++ b/include/linux/power/bq24190_charger.h @@ -0,0 +1,16 @@ +/* + * Platform data for the TI bq24190 battery charger driver. + * + * 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 _BQ24190_CHARGER_H_ +#define _BQ24190_CHARGER_H_ + +struct bq24190_platform_data { + unsigned int gpio_int; /* GPIO pin that's connected to INT# */ +}; + +#endif diff --git a/include/linux/power/smartreflex.h b/include/linux/power/smartreflex.h index c0f44c2b006d..d8b187c3925d 100644 --- a/include/linux/power/smartreflex.h +++ b/include/linux/power/smartreflex.h @@ -299,11 +299,11 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm); void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data); /* Smartreflex driver hooks to be called from Smartreflex class driver */ -int sr_enable(struct voltagedomain *voltdm, unsigned long volt); -void sr_disable(struct voltagedomain *voltdm); -int sr_configure_errgen(struct voltagedomain *voltdm); -int sr_disable_errgen(struct voltagedomain *voltdm); -int sr_configure_minmax(struct voltagedomain *voltdm); +int sr_enable(struct omap_sr *sr, unsigned long volt); +void sr_disable(struct omap_sr *sr); +int sr_configure_errgen(struct omap_sr *sr); +int sr_disable_errgen(struct omap_sr *sr); +int sr_configure_minmax(struct omap_sr *sr); /* API to register the smartreflex class driver with the smartreflex driver */ int sr_register_class(struct omap_sr_class_data *class_data); diff --git a/include/linux/power/twl4030_madc_battery.h b/include/linux/power/twl4030_madc_battery.h new file mode 100644 index 000000000000..23110dc77726 --- /dev/null +++ b/include/linux/power/twl4030_madc_battery.h @@ -0,0 +1,39 @@ +/* + * Dumb driver for LiIon batteries using TWL4030 madc. + * + * Copyright 2013 Golden Delicious Computers + * Nikolaus Schaller <hns@goldelico.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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef __TWL4030_MADC_BATTERY_H +#define __TWL4030_MADC_BATTERY_H + +/* + * Usually we can assume 100% @ 4.15V and 0% @ 3.3V but curves differ for + * charging and discharging! + */ + +struct twl4030_madc_bat_calibration { + short voltage; /* in mV - specify -1 for end of list */ + short level; /* in percent (0 .. 100%) */ +}; + +struct twl4030_madc_bat_platform_data { + unsigned int capacity; /* total capacity in uAh */ + struct twl4030_madc_bat_calibration *charging; + int charging_size; + struct twl4030_madc_bat_calibration *discharging; + int discharging_size; +}; + +#endif diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 002a99f96331..5c2600630dc9 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -15,6 +15,7 @@ #include <linux/workqueue.h> #include <linux/leds.h> +#include <linux/spinlock.h> struct device; @@ -162,6 +163,8 @@ union power_supply_propval { const char *strval; }; +struct device_node; + struct power_supply { const char *name; enum power_supply_type type; @@ -171,6 +174,10 @@ struct power_supply { char **supplied_to; size_t num_supplicants; + char **supplied_from; + size_t num_supplies; + struct device_node *of_node; + int (*get_property)(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val); @@ -188,6 +195,8 @@ struct power_supply { /* private */ struct device *dev; struct work_struct changed_work; + spinlock_t changed_lock; + bool changed; #ifdef CONFIG_THERMAL struct thermal_zone_device *tzd; struct thermal_cooling_device *tcd; diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h index 7db3eb93a079..1d2cd21242e8 100644 --- a/include/linux/pps_kernel.h +++ b/include/linux/pps_kernel.h @@ -80,7 +80,7 @@ struct pps_device { * Global variables */ -extern struct device_attribute pps_attrs[]; +extern const struct attribute_group *pps_groups[]; /* * Internal functions. diff --git a/include/linux/preempt.h b/include/linux/preempt.h index 5a710b9c578e..a3d9dc8c2c00 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -6,101 +6,113 @@ * preempt_count (used for kernel preemption, interrupt count, etc.) */ -#include <linux/thread_info.h> #include <linux/linkage.h> #include <linux/list.h> +/* + * We use the MSB mostly because its available; see <linux/preempt_mask.h> for + * the other bits -- can't include that header due to inclusion hell. + */ +#define PREEMPT_NEED_RESCHED 0x80000000 + +#include <asm/preempt.h> + #if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER) - extern void add_preempt_count(int val); - extern void sub_preempt_count(int val); +extern void preempt_count_add(int val); +extern void preempt_count_sub(int val); +#define preempt_count_dec_and_test() ({ preempt_count_sub(1); should_resched(); }) #else -# define add_preempt_count(val) do { preempt_count() += (val); } while (0) -# define sub_preempt_count(val) do { preempt_count() -= (val); } while (0) +#define preempt_count_add(val) __preempt_count_add(val) +#define preempt_count_sub(val) __preempt_count_sub(val) +#define preempt_count_dec_and_test() __preempt_count_dec_and_test() #endif -#define inc_preempt_count() add_preempt_count(1) -#define dec_preempt_count() sub_preempt_count(1) - -#define preempt_count() (current_thread_info()->preempt_count) - -#ifdef CONFIG_PREEMPT - -asmlinkage void preempt_schedule(void); - -#define preempt_check_resched() \ -do { \ - if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ - preempt_schedule(); \ -} while (0) - -#else /* !CONFIG_PREEMPT */ - -#define preempt_check_resched() do { } while (0) - -#endif /* CONFIG_PREEMPT */ +#define __preempt_count_inc() __preempt_count_add(1) +#define __preempt_count_dec() __preempt_count_sub(1) +#define preempt_count_inc() preempt_count_add(1) +#define preempt_count_dec() preempt_count_sub(1) #ifdef CONFIG_PREEMPT_COUNT #define preempt_disable() \ do { \ - inc_preempt_count(); \ + preempt_count_inc(); \ barrier(); \ } while (0) #define sched_preempt_enable_no_resched() \ do { \ barrier(); \ - dec_preempt_count(); \ + preempt_count_dec(); \ } while (0) -#define preempt_enable_no_resched() sched_preempt_enable_no_resched() +#define preempt_enable_no_resched() sched_preempt_enable_no_resched() +#ifdef CONFIG_PREEMPT #define preempt_enable() \ do { \ - preempt_enable_no_resched(); \ barrier(); \ - preempt_check_resched(); \ + if (unlikely(preempt_count_dec_and_test())) \ + __preempt_schedule(); \ } while (0) -/* For debugging and tracer internals only! */ -#define add_preempt_count_notrace(val) \ - do { preempt_count() += (val); } while (0) -#define sub_preempt_count_notrace(val) \ - do { preempt_count() -= (val); } while (0) -#define inc_preempt_count_notrace() add_preempt_count_notrace(1) -#define dec_preempt_count_notrace() sub_preempt_count_notrace(1) +#define preempt_check_resched() \ +do { \ + if (should_resched()) \ + __preempt_schedule(); \ +} while (0) + +#else +#define preempt_enable() preempt_enable_no_resched() +#define preempt_check_resched() do { } while (0) +#endif #define preempt_disable_notrace() \ do { \ - inc_preempt_count_notrace(); \ + __preempt_count_inc(); \ barrier(); \ } while (0) #define preempt_enable_no_resched_notrace() \ do { \ barrier(); \ - dec_preempt_count_notrace(); \ + __preempt_count_dec(); \ } while (0) -/* preempt_check_resched is OK to trace */ +#ifdef CONFIG_PREEMPT + +#ifndef CONFIG_CONTEXT_TRACKING +#define __preempt_schedule_context() __preempt_schedule() +#endif + #define preempt_enable_notrace() \ do { \ - preempt_enable_no_resched_notrace(); \ barrier(); \ - preempt_check_resched(); \ + if (unlikely(__preempt_count_dec_and_test())) \ + __preempt_schedule_context(); \ } while (0) +#else +#define preempt_enable_notrace() preempt_enable_no_resched_notrace() +#endif #else /* !CONFIG_PREEMPT_COUNT */ -#define preempt_disable() do { } while (0) -#define sched_preempt_enable_no_resched() do { } while (0) -#define preempt_enable_no_resched() do { } while (0) -#define preempt_enable() do { } while (0) - -#define preempt_disable_notrace() do { } while (0) -#define preempt_enable_no_resched_notrace() do { } while (0) -#define preempt_enable_notrace() do { } while (0) +/* + * Even if we don't have any preemption, we need preempt disable/enable + * to be barriers, so that we don't have things like get_user/put_user + * that can cause faults and scheduling migrate into our preempt-protected + * region. + */ +#define preempt_disable() barrier() +#define sched_preempt_enable_no_resched() barrier() +#define preempt_enable_no_resched() barrier() +#define preempt_enable() barrier() +#define preempt_check_resched() do { } while (0) + +#define preempt_disable_notrace() barrier() +#define preempt_enable_no_resched_notrace() barrier() +#define preempt_enable_notrace() barrier() #endif /* CONFIG_PREEMPT_COUNT */ diff --git a/include/linux/preempt_mask.h b/include/linux/preempt_mask.h new file mode 100644 index 000000000000..931bc616219f --- /dev/null +++ b/include/linux/preempt_mask.h @@ -0,0 +1,122 @@ +#ifndef LINUX_PREEMPT_MASK_H +#define LINUX_PREEMPT_MASK_H + +#include <linux/preempt.h> +#include <asm/hardirq.h> + +/* + * We put the hardirq and softirq counter into the preemption + * counter. The bitmask has the following meaning: + * + * - bits 0-7 are the preemption count (max preemption depth: 256) + * - bits 8-15 are the softirq count (max # of softirqs: 256) + * + * The hardirq count can in theory reach the same as NR_IRQS. + * In reality, the number of nested IRQS is limited to the stack + * size as well. For archs with over 1000 IRQS it is not practical + * to expect that they will all nest. We give a max of 10 bits for + * hardirq nesting. An arch may choose to give less than 10 bits. + * m68k expects it to be 8. + * + * - bits 16-25 are the hardirq count (max # of nested hardirqs: 1024) + * - bit 26 is the NMI_MASK + * - bit 27 is the PREEMPT_ACTIVE flag + * + * PREEMPT_MASK: 0x000000ff + * SOFTIRQ_MASK: 0x0000ff00 + * HARDIRQ_MASK: 0x03ff0000 + * NMI_MASK: 0x04000000 + */ +#define PREEMPT_BITS 8 +#define SOFTIRQ_BITS 8 +#define NMI_BITS 1 + +#define MAX_HARDIRQ_BITS 10 + +#ifndef HARDIRQ_BITS +# define HARDIRQ_BITS MAX_HARDIRQ_BITS +#endif + +#if HARDIRQ_BITS > MAX_HARDIRQ_BITS +#error HARDIRQ_BITS too high! +#endif + +#define PREEMPT_SHIFT 0 +#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) +#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) +#define NMI_SHIFT (HARDIRQ_SHIFT + HARDIRQ_BITS) + +#define __IRQ_MASK(x) ((1UL << (x))-1) + +#define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) +#define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) +#define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) +#define NMI_MASK (__IRQ_MASK(NMI_BITS) << NMI_SHIFT) + +#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) +#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) +#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) +#define NMI_OFFSET (1UL << NMI_SHIFT) + +#define SOFTIRQ_DISABLE_OFFSET (2 * SOFTIRQ_OFFSET) + +#ifndef PREEMPT_ACTIVE +#define PREEMPT_ACTIVE_BITS 1 +#define PREEMPT_ACTIVE_SHIFT (NMI_SHIFT + NMI_BITS) +#define PREEMPT_ACTIVE (__IRQ_MASK(PREEMPT_ACTIVE_BITS) << PREEMPT_ACTIVE_SHIFT) +#endif + +#if PREEMPT_ACTIVE < (1 << (NMI_SHIFT + NMI_BITS)) +#error PREEMPT_ACTIVE is too low! +#endif + +#define hardirq_count() (preempt_count() & HARDIRQ_MASK) +#define softirq_count() (preempt_count() & SOFTIRQ_MASK) +#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \ + | NMI_MASK)) + +/* + * Are we doing bottom half or hardware interrupt processing? + * Are we in a softirq context? Interrupt context? + * in_softirq - Are we currently processing softirq or have bh disabled? + * in_serving_softirq - Are we currently processing softirq? + */ +#define in_irq() (hardirq_count()) +#define in_softirq() (softirq_count()) +#define in_interrupt() (irq_count()) +#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET) + +/* + * Are we in NMI context? + */ +#define in_nmi() (preempt_count() & NMI_MASK) + +#if defined(CONFIG_PREEMPT_COUNT) +# define PREEMPT_CHECK_OFFSET 1 +#else +# define PREEMPT_CHECK_OFFSET 0 +#endif + +/* + * Are we running in atomic context? WARNING: this macro cannot + * always detect atomic context; in particular, it cannot know about + * held spinlocks in non-preemptible kernels. Thus it should not be + * used in the general case to determine whether sleeping is possible. + * Do not use in_atomic() in driver code. + */ +#define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != 0) + +/* + * Check whether we were atomic before we did preempt_disable(): + * (used by the scheduler, *after* releasing the kernel lock) + */ +#define in_atomic_preempt_off() \ + ((preempt_count() & ~PREEMPT_ACTIVE) != PREEMPT_CHECK_OFFSET) + +#ifdef CONFIG_PREEMPT_COUNT +# define preemptible() (preempt_count() == 0 && !irqs_disabled()) +#else +# define preemptible() 0 +#endif + +#endif /* LINUX_PREEMPT_MASK_H */ diff --git a/include/linux/printk.h b/include/linux/printk.h index 1249a54d17e0..e6131a782481 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -1,8 +1,10 @@ #ifndef __KERNEL_PRINTK__ #define __KERNEL_PRINTK__ +#include <stdarg.h> #include <linux/init.h> #include <linux/kern_levels.h> +#include <linux/linkage.h> extern const char linux_banner[]; extern const char linux_proc_banner[]; @@ -95,8 +97,14 @@ int no_printk(const char *fmt, ...) return 0; } +#ifdef CONFIG_EARLY_PRINTK extern asmlinkage __printf(1, 2) void early_printk(const char *fmt, ...); +void early_vprintk(const char *fmt, va_list ap); +#else +static inline __printf(1, 2) __cold +void early_printk(const char *s, ...) { } +#endif #ifdef CONFIG_PRINTK asmlinkage __printf(5, 0) @@ -134,8 +142,13 @@ extern int printk_delay_msec; extern int dmesg_restrict; extern int kptr_restrict; +extern void wake_up_klogd(void); + void log_buf_kexec_setup(void); void __init setup_log_buf(int early); +void dump_stack_set_arch_desc(const char *fmt, ...); +void dump_stack_print_info(const char *log_lvl); +void show_regs_print_info(const char *log_lvl); #else static inline __printf(1, 0) int vprintk(const char *s, va_list args) @@ -162,6 +175,10 @@ static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, return false; } +static inline void wake_up_klogd(void) +{ +} + static inline void log_buf_kexec_setup(void) { } @@ -169,9 +186,21 @@ static inline void log_buf_kexec_setup(void) static inline void setup_log_buf(int early) { } + +static inline void dump_stack_set_arch_desc(const char *fmt, ...) +{ +} + +static inline void dump_stack_print_info(const char *log_lvl) +{ +} + +static inline void show_regs_print_info(const char *log_lvl) +{ +} #endif -extern void dump_stack(void) __cold; +extern asmlinkage void dump_stack(void) __cold; #ifndef pr_fmt #define pr_fmt(fmt) fmt diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 8307f2f94d86..608e60a74c3c 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -1,316 +1,79 @@ -#ifndef _LINUX_PROC_FS_H -#define _LINUX_PROC_FS_H - -#include <linux/slab.h> -#include <linux/fs.h> -#include <linux/spinlock.h> -#include <linux/magic.h> -#include <linux/atomic.h> - -struct net; -struct completion; -struct mm_struct; - /* * The proc filesystem constants/structures */ +#ifndef _LINUX_PROC_FS_H +#define _LINUX_PROC_FS_H -/* - * Offset of the first process in the /proc root directory.. - */ -#define FIRST_PROCESS_ENTRY 256 - -/* Worst case buffer size needed for holding an integer. */ -#define PROC_NUMBUF 13 - -/* - * We always define these enumerators - */ - -enum { - PROC_ROOT_INO = 1, - PROC_IPC_INIT_INO = 0xEFFFFFFFU, - PROC_UTS_INIT_INO = 0xEFFFFFFEU, - PROC_USER_INIT_INO = 0xEFFFFFFDU, - PROC_PID_INIT_INO = 0xEFFFFFFCU, -}; - -/* - * This is not completely implemented yet. The idea is to - * create an in-memory tree (like the actual /proc filesystem - * tree) of these proc_dir_entries, so that we can dynamically - * add new files to /proc. - * - * The "next" pointer creates a linked list of one /proc directory, - * while parent/subdir create the directory structure (every - * /proc file has a parent, but "subdir" is NULL for all - * non-directory entries). - */ - -typedef int (read_proc_t)(char *page, char **start, off_t off, - int count, int *eof, void *data); -typedef int (write_proc_t)(struct file *file, const char __user *buffer, - unsigned long count, void *data); - -struct proc_dir_entry { - unsigned int low_ino; - umode_t mode; - nlink_t nlink; - kuid_t uid; - kgid_t gid; - loff_t size; - const struct inode_operations *proc_iops; - /* - * NULL ->proc_fops means "PDE is going away RSN" or - * "PDE is just created". In either case, e.g. ->read_proc won't be - * called because it's too late or too early, respectively. - * - * If you're allocating ->proc_fops dynamically, save a pointer - * somewhere. - */ - const struct file_operations *proc_fops; - struct proc_dir_entry *next, *parent, *subdir; - void *data; - read_proc_t *read_proc; - write_proc_t *write_proc; - atomic_t count; /* use count */ - int pde_users; /* number of callers into module in progress */ - struct completion *pde_unload_completion; - struct list_head pde_openers; /* who did ->open, but not ->release */ - spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */ - u8 namelen; - char name[]; -}; - -enum kcore_type { - KCORE_TEXT, - KCORE_VMALLOC, - KCORE_RAM, - KCORE_VMEMMAP, - KCORE_OTHER, -}; - -struct kcore_list { - struct list_head list; - unsigned long addr; - size_t size; - int type; -}; +#include <linux/types.h> +#include <linux/fs.h> -struct vmcore { - struct list_head list; - unsigned long long paddr; - unsigned long long size; - loff_t offset; -}; +struct proc_dir_entry; #ifdef CONFIG_PROC_FS extern void proc_root_init(void); - -void proc_flush_task(struct task_struct *task); - -extern struct proc_dir_entry *create_proc_entry(const char *name, umode_t mode, - struct proc_dir_entry *parent); -struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, - struct proc_dir_entry *parent, - const struct file_operations *proc_fops, - void *data); -extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent); - -struct pid_namespace; - -extern int pid_ns_prepare_proc(struct pid_namespace *ns); -extern void pid_ns_release_proc(struct pid_namespace *ns); - -/* - * proc_tty.c - */ -struct tty_driver; -#ifdef CONFIG_TTY -extern void proc_tty_init(void); -#else -static inline void proc_tty_init(void) -{ } -#endif -extern void proc_tty_register_driver(struct tty_driver *driver); -extern void proc_tty_unregister_driver(struct tty_driver *driver); - -/* - * proc_devtree.c - */ -#ifdef CONFIG_PROC_DEVICETREE -struct device_node; -struct property; -extern void proc_device_tree_init(void); -extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *); -extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop); -extern void proc_device_tree_remove_prop(struct proc_dir_entry *pde, - struct property *prop); -extern void proc_device_tree_update_prop(struct proc_dir_entry *pde, - struct property *newprop, - struct property *oldprop); -#endif /* CONFIG_PROC_DEVICETREE */ +extern void proc_flush_task(struct task_struct *); extern struct proc_dir_entry *proc_symlink(const char *, struct proc_dir_entry *, const char *); -extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *); -extern struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, - struct proc_dir_entry *parent); - -static inline struct proc_dir_entry *proc_create(const char *name, umode_t mode, - struct proc_dir_entry *parent, const struct file_operations *proc_fops) +extern struct proc_dir_entry *proc_mkdir(const char *, struct proc_dir_entry *); +extern struct proc_dir_entry *proc_mkdir_data(const char *, umode_t, + struct proc_dir_entry *, void *); +extern struct proc_dir_entry *proc_mkdir_mode(const char *, umode_t, + struct proc_dir_entry *); + +extern struct proc_dir_entry *proc_create_data(const char *, umode_t, + struct proc_dir_entry *, + const struct file_operations *, + void *); + +static inline struct proc_dir_entry *proc_create( + const char *name, umode_t mode, struct proc_dir_entry *parent, + const struct file_operations *proc_fops) { return proc_create_data(name, mode, parent, proc_fops, NULL); } -static inline struct proc_dir_entry *create_proc_read_entry(const char *name, - umode_t mode, struct proc_dir_entry *base, - read_proc_t *read_proc, void * data) -{ - struct proc_dir_entry *res=create_proc_entry(name,mode,base); - if (res) { - res->read_proc=read_proc; - res->data=data; - } - return res; -} - -extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, - struct proc_dir_entry *parent); - -extern struct file *proc_ns_fget(int fd); -extern bool proc_ns_inode(struct inode *inode); +extern void proc_set_size(struct proc_dir_entry *, loff_t); +extern void proc_set_user(struct proc_dir_entry *, kuid_t, kgid_t); +extern void *PDE_DATA(const struct inode *); +extern void *proc_get_parent_data(const struct inode *); +extern void proc_remove(struct proc_dir_entry *); +extern void remove_proc_entry(const char *, struct proc_dir_entry *); +extern int remove_proc_subtree(const char *, struct proc_dir_entry *); -extern int proc_alloc_inum(unsigned int *pino); -extern void proc_free_inum(unsigned int inum); -#else +#else /* CONFIG_PROC_FS */ static inline void proc_flush_task(struct task_struct *task) { } -static inline struct proc_dir_entry *create_proc_entry(const char *name, - umode_t mode, struct proc_dir_entry *parent) { return NULL; } - -#define proc_create(name, mode, parent, fops) ({ (void)(mode), NULL; }) - -static inline struct proc_dir_entry *proc_create_data(const char *name, - umode_t mode, struct proc_dir_entry *parent, - const struct file_operations *proc_fops, void *data) -{ - return NULL; -} -#define remove_proc_entry(name, parent) do {} while (0) - static inline struct proc_dir_entry *proc_symlink(const char *name, - struct proc_dir_entry *parent,const char *dest) {return NULL;} + struct proc_dir_entry *parent,const char *dest) { return NULL;} static inline struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) {return NULL;} +static inline struct proc_dir_entry *proc_mkdir_data(const char *name, + umode_t mode, struct proc_dir_entry *parent, void *data) { return NULL; } static inline struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, struct proc_dir_entry *parent) { return NULL; } +#define proc_create(name, mode, parent, proc_fops) ({NULL;}) +#define proc_create_data(name, mode, parent, proc_fops, data) ({NULL;}) -static inline struct proc_dir_entry *create_proc_read_entry(const char *name, - umode_t mode, struct proc_dir_entry *base, - read_proc_t *read_proc, void * data) { return NULL; } - -struct tty_driver; -static inline void proc_tty_register_driver(struct tty_driver *driver) {}; -static inline void proc_tty_unregister_driver(struct tty_driver *driver) {}; +static inline void proc_set_size(struct proc_dir_entry *de, loff_t size) {} +static inline void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid) {} +static inline void *PDE_DATA(const struct inode *inode) {BUG(); return NULL;} +static inline void *proc_get_parent_data(const struct inode *inode) { BUG(); return NULL; } -static inline int pid_ns_prepare_proc(struct pid_namespace *ns) -{ - return 0; -} - -static inline void pid_ns_release_proc(struct pid_namespace *ns) -{ -} - -static inline struct file *proc_ns_fget(int fd) -{ - return ERR_PTR(-EINVAL); -} - -static inline bool proc_ns_inode(struct inode *inode) -{ - return false; -} +static inline void proc_remove(struct proc_dir_entry *de) {} +#define remove_proc_entry(name, parent) do {} while (0) +static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) { return 0; } -static inline int proc_alloc_inum(unsigned int *inum) -{ - *inum = 1; - return 0; -} -static inline void proc_free_inum(unsigned int inum) -{ -} #endif /* CONFIG_PROC_FS */ -#if !defined(CONFIG_PROC_KCORE) -static inline void -kclist_add(struct kcore_list *new, void *addr, size_t size, int type) +static inline struct proc_dir_entry *proc_net_mkdir( + struct net *net, const char *name, struct proc_dir_entry *parent) { + return proc_mkdir_data(name, 0, parent, net); } -#else -extern void kclist_add(struct kcore_list *, void *, size_t, int type); -#endif - -struct nsproxy; -struct proc_ns_operations { - const char *name; - int type; - void *(*get)(struct task_struct *task); - void (*put)(void *ns); - int (*install)(struct nsproxy *nsproxy, void *ns); - unsigned int (*inum)(void *ns); -}; -extern const struct proc_ns_operations netns_operations; -extern const struct proc_ns_operations utsns_operations; -extern const struct proc_ns_operations ipcns_operations; -extern const struct proc_ns_operations pidns_operations; -extern const struct proc_ns_operations userns_operations; -extern const struct proc_ns_operations mntns_operations; - -union proc_op { - int (*proc_get_link)(struct dentry *, struct path *); - int (*proc_read)(struct task_struct *task, char *page); - int (*proc_show)(struct seq_file *m, - struct pid_namespace *ns, struct pid *pid, - struct task_struct *task); -}; - -struct ctl_table_header; -struct ctl_table; - -struct proc_inode { - struct pid *pid; - int fd; - union proc_op op; - struct proc_dir_entry *pde; - struct ctl_table_header *sysctl; - struct ctl_table *sysctl_entry; - void *ns; - const struct proc_ns_operations *ns_ops; - struct inode vfs_inode; -}; - -static inline struct proc_inode *PROC_I(const struct inode *inode) -{ - return container_of(inode, struct proc_inode, vfs_inode); -} - -static inline struct proc_dir_entry *PDE(const struct inode *inode) -{ - return PROC_I(inode)->pde; -} - -static inline struct net *PDE_NET(struct proc_dir_entry *pde) -{ - return pde->parent->data; -} - -#include <linux/signal.h> -void render_sigset_t(struct seq_file *m, const char *header, sigset_t *set); #endif /* _LINUX_PROC_FS_H */ diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h new file mode 100644 index 000000000000..34a1e105bef4 --- /dev/null +++ b/include/linux/proc_ns.h @@ -0,0 +1,74 @@ +/* + * procfs namespace bits + */ +#ifndef _LINUX_PROC_NS_H +#define _LINUX_PROC_NS_H + +struct pid_namespace; +struct nsproxy; + +struct proc_ns_operations { + const char *name; + int type; + void *(*get)(struct task_struct *task); + void (*put)(void *ns); + int (*install)(struct nsproxy *nsproxy, void *ns); + unsigned int (*inum)(void *ns); +}; + +struct proc_ns { + void *ns; + const struct proc_ns_operations *ns_ops; +}; + +extern const struct proc_ns_operations netns_operations; +extern const struct proc_ns_operations utsns_operations; +extern const struct proc_ns_operations ipcns_operations; +extern const struct proc_ns_operations pidns_operations; +extern const struct proc_ns_operations userns_operations; +extern const struct proc_ns_operations mntns_operations; + +/* + * We always define these enumerators + */ +enum { + PROC_ROOT_INO = 1, + PROC_IPC_INIT_INO = 0xEFFFFFFFU, + PROC_UTS_INIT_INO = 0xEFFFFFFEU, + PROC_USER_INIT_INO = 0xEFFFFFFDU, + PROC_PID_INIT_INO = 0xEFFFFFFCU, +}; + +#ifdef CONFIG_PROC_FS + +extern int pid_ns_prepare_proc(struct pid_namespace *ns); +extern void pid_ns_release_proc(struct pid_namespace *ns); +extern struct file *proc_ns_fget(int fd); +extern struct proc_ns *get_proc_ns(struct inode *); +extern int proc_alloc_inum(unsigned int *pino); +extern void proc_free_inum(unsigned int inum); +extern bool proc_ns_inode(struct inode *inode); + +#else /* CONFIG_PROC_FS */ + +static inline int pid_ns_prepare_proc(struct pid_namespace *ns) { return 0; } +static inline void pid_ns_release_proc(struct pid_namespace *ns) {} + +static inline struct file *proc_ns_fget(int fd) +{ + return ERR_PTR(-EINVAL); +} + +static inline struct proc_ns *get_proc_ns(struct inode *inode) { return NULL; } + +static inline int proc_alloc_inum(unsigned int *inum) +{ + *inum = 1; + return 0; +} +static inline void proc_free_inum(unsigned int inum) {} +static inline bool proc_ns_inode(struct inode *inode) { return false; } + +#endif /* CONFIG_PROC_FS */ + +#endif /* _LINUX_PROC_NS_H */ diff --git a/include/linux/profile.h b/include/linux/profile.h index 21123902366d..aaad3861beb8 100644 --- a/include/linux/profile.h +++ b/include/linux/profile.h @@ -18,10 +18,10 @@ struct pt_regs; struct notifier_block; #if defined(CONFIG_PROFILING) && defined(CONFIG_PROC_FS) -void create_prof_cpu_mask(struct proc_dir_entry *de); +void create_prof_cpu_mask(void); int create_proc_profile(void); #else -static inline void create_prof_cpu_mask(struct proc_dir_entry *de) +static inline void create_prof_cpu_mask(void) { } diff --git a/include/linux/pstore.h b/include/linux/pstore.h index 75d01760c911..abd437d0a8a7 100644 --- a/include/linux/pstore.h +++ b/include/linux/pstore.h @@ -35,6 +35,10 @@ enum pstore_type_id { PSTORE_TYPE_MCE = 1, PSTORE_TYPE_CONSOLE = 2, PSTORE_TYPE_FTRACE = 3, + /* PPC64 partition types */ + PSTORE_TYPE_PPC_RTAS = 4, + PSTORE_TYPE_PPC_OF = 5, + PSTORE_TYPE_PPC_COMMON = 6, PSTORE_TYPE_UNKNOWN = 255 }; @@ -51,15 +55,15 @@ struct pstore_info { int (*close)(struct pstore_info *psi); ssize_t (*read)(u64 *id, enum pstore_type_id *type, int *count, struct timespec *time, char **buf, - struct pstore_info *psi); + bool *compressed, struct pstore_info *psi); int (*write)(enum pstore_type_id type, enum kmsg_dump_reason reason, u64 *id, - unsigned int part, int count, size_t size, - struct pstore_info *psi); + unsigned int part, int count, bool compressed, + size_t size, struct pstore_info *psi); int (*write_buf)(enum pstore_type_id type, enum kmsg_dump_reason reason, u64 *id, - unsigned int part, const char *buf, size_t size, - struct pstore_info *psi); + unsigned int part, const char *buf, bool compressed, + size_t size, struct pstore_info *psi); int (*erase)(enum pstore_type_id type, u64 id, int count, struct timespec time, struct pstore_info *psi); diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h index cb6ab5feab67..9974975d40db 100644 --- a/include/linux/pstore_ram.h +++ b/include/linux/pstore_ram.h @@ -26,6 +26,13 @@ struct persistent_ram_buffer; struct rs_control; +struct persistent_ram_ecc_info { + int block_size; + int ecc_size; + int symsize; + int poly; +}; + struct persistent_ram_zone { phys_addr_t paddr; size_t size; @@ -39,15 +46,14 @@ struct persistent_ram_zone { struct rs_control *rs_decoder; int corrected_bytes; int bad_blocks; - int ecc_block_size; - int ecc_size; + struct persistent_ram_ecc_info ecc_info; char *old_log; size_t old_log_size; }; struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size, - u32 sig, int ecc_size); + u32 sig, struct persistent_ram_ecc_info *ecc_info); void persistent_ram_free(struct persistent_ram_zone *prz); void persistent_ram_zap(struct persistent_ram_zone *prz); @@ -74,7 +80,7 @@ struct ramoops_platform_data { unsigned long console_size; unsigned long ftrace_size; int dump_oops; - int ecc_size; + struct persistent_ram_ecc_info ecc_info; }; #endif diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 89573a33ab3c..07d0df6bf768 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -142,9 +142,6 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace) { INIT_LIST_HEAD(&child->ptrace_entry); INIT_LIST_HEAD(&child->ptraced); -#ifdef CONFIG_HAVE_HW_BREAKPOINT - atomic_set(&child->ptrace_bp_refcnt, 1); -#endif child->jobctl = 0; child->ptrace = 0; child->parent = child->real_parent; @@ -351,11 +348,4 @@ extern int task_current_syscall(struct task_struct *target, long *callno, unsigned long args[6], unsigned int maxargs, unsigned long *sp, unsigned long *pc); -#ifdef CONFIG_HAVE_HW_BREAKPOINT -extern int ptrace_get_breakpoints(struct task_struct *tsk); -extern void ptrace_put_breakpoints(struct task_struct *tsk); -#else -static inline void ptrace_put_breakpoints(struct task_struct *tsk) { } -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ - #endif diff --git a/include/linux/pvclock_gtod.h b/include/linux/pvclock_gtod.h index 0ca75825b60d..a71d2dbd3610 100644 --- a/include/linux/pvclock_gtod.h +++ b/include/linux/pvclock_gtod.h @@ -3,6 +3,13 @@ #include <linux/notifier.h> +/* + * The pvclock gtod notifier is called when the system time is updated + * and is used to keep guest time synchronized with host time. + * + * The 'action' parameter in the notifier function is false (0), or + * true (non-zero) if system time was stepped. + */ extern int pvclock_gtod_register_notifier(struct notifier_block *nb); extern int pvclock_gtod_unregister_notifier(struct notifier_block *nb); diff --git a/include/linux/pwm.h b/include/linux/pwm.h index a4df2042b79c..f0feafd184a0 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -76,6 +76,7 @@ enum pwm_polarity { enum { PWMF_REQUESTED = 1 << 0, PWMF_ENABLED = 1 << 1, + PWMF_EXPORTED = 1 << 2, }; struct pwm_device { @@ -86,7 +87,9 @@ struct pwm_device { struct pwm_chip *chip; void *chip_data; - unsigned int period; /* in nanoseconds */ + unsigned int period; /* in nanoseconds */ + unsigned int duty_cycle; /* in nanoseconds */ + enum pwm_polarity polarity; }; static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period) @@ -100,6 +103,17 @@ static inline unsigned int pwm_get_period(struct pwm_device *pwm) return pwm ? pwm->period : 0; } +static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty) +{ + if (pwm) + pwm->duty_cycle = duty; +} + +static inline unsigned int pwm_get_duty_cycle(struct pwm_device *pwm) +{ + return pwm ? pwm->duty_cycle : 0; +} + /* * pwm_set_polarity - configure the polarity of a PWM signal */ @@ -278,4 +292,17 @@ static inline void pwm_add_table(struct pwm_lookup *table, size_t num) } #endif +#ifdef CONFIG_PWM_SYSFS +void pwmchip_sysfs_export(struct pwm_chip *chip); +void pwmchip_sysfs_unexport(struct pwm_chip *chip); +#else +static inline void pwmchip_sysfs_export(struct pwm_chip *chip) +{ +} + +static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip) +{ +} +#endif /* CONFIG_PWM_SYSFS */ + #endif /* __LINUX_PWM_H */ diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h index 467cc6307b62..49444203328a 100644 --- a/include/linux/pxa2xx_ssp.h +++ b/include/linux/pxa2xx_ssp.h @@ -21,6 +21,8 @@ #include <linux/list.h> #include <linux/io.h> +#include <linux/of.h> + /* * SSP Serial Port Registers @@ -190,6 +192,8 @@ struct ssp_device { int irq; int drcmr_rx; int drcmr_tx; + + struct device_node *of_node; }; /** @@ -218,11 +222,18 @@ static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg) #ifdef CONFIG_ARCH_PXA struct ssp_device *pxa_ssp_request(int port, const char *label); void pxa_ssp_free(struct ssp_device *); +struct ssp_device *pxa_ssp_request_of(const struct device_node *of_node, + const char *label); #else static inline struct ssp_device *pxa_ssp_request(int port, const char *label) { return NULL; } +static inline struct ssp_device *pxa_ssp_request_of(const struct device_node *n, + const char *name) +{ + return NULL; +} static inline void pxa_ssp_free(struct ssp_device *ssp) {} #endif diff --git a/include/linux/quota.h b/include/linux/quota.h index d13371134c59..cc7494a35429 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -328,6 +328,7 @@ struct quotactl_ops { int (*set_dqblk)(struct super_block *, struct kqid, struct fs_disk_quota *); int (*get_xstate)(struct super_block *, struct fs_quota_stat *); int (*set_xstate)(struct super_block *, unsigned int, int); + int (*get_xstatev)(struct super_block *, struct fs_quota_statv *); }; struct quota_format_type { diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 1c50093ae656..6965fe394c3b 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -41,6 +41,7 @@ void __quota_error(struct super_block *sb, const char *func, void inode_add_rsv_space(struct inode *inode, qsize_t number); void inode_claim_rsv_space(struct inode *inode, qsize_t number); void inode_sub_rsv_space(struct inode *inode, qsize_t number); +void inode_reclaim_rsv_space(struct inode *inode, qsize_t number); void dquot_initialize(struct inode *inode); void dquot_drop(struct inode *inode); @@ -59,6 +60,7 @@ int dquot_alloc_inode(const struct inode *inode); int dquot_claim_space_nodirty(struct inode *inode, qsize_t number); void dquot_free_inode(const struct inode *inode); +void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number); int dquot_disable(struct super_block *sb, int type, unsigned int flags); /* Suspend quotas on remount RO */ @@ -238,6 +240,13 @@ static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) return 0; } +static inline int dquot_reclaim_space_nodirty(struct inode *inode, + qsize_t number) +{ + inode_sub_bytes(inode, number); + return 0; +} + static inline int dquot_disable(struct super_block *sb, int type, unsigned int flags) { @@ -336,6 +345,12 @@ static inline int dquot_claim_block(struct inode *inode, qsize_t nr) return ret; } +static inline void dquot_reclaim_block(struct inode *inode, qsize_t nr) +{ + dquot_reclaim_space_nodirty(inode, nr << inode->i_blkbits); + mark_inode_dirty_sync(inode); +} + static inline void dquot_free_space_nodirty(struct inode *inode, qsize_t nr) { __dquot_free_space(inode, nr, 0); diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index ffc444c38b0a..403940787be1 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -231,6 +231,7 @@ unsigned long radix_tree_next_hole(struct radix_tree_root *root, unsigned long radix_tree_prev_hole(struct radix_tree_root *root, unsigned long index, unsigned long max_scan); int radix_tree_preload(gfp_t gfp_mask); +int radix_tree_maybe_preload(gfp_t gfp_mask); void radix_tree_init(void); void *radix_tree_tag_set(struct radix_tree_root *root, unsigned long index, unsigned int tag); diff --git a/include/linux/raid/pq.h b/include/linux/raid/pq.h index 8dfaa2ce2e95..73069cb6c54a 100644 --- a/include/linux/raid/pq.h +++ b/include/linux/raid/pq.h @@ -101,6 +101,7 @@ extern const struct raid6_calls raid6_altivec8; extern const struct raid6_calls raid6_avx2x1; extern const struct raid6_calls raid6_avx2x2; extern const struct raid6_calls raid6_avx2x4; +extern const struct raid6_calls raid6_tilegx8; struct raid6_recov_calls { void (*data2)(int, size_t, int, int, void **); @@ -114,6 +115,11 @@ extern const struct raid6_recov_calls raid6_recov_intx1; extern const struct raid6_recov_calls raid6_recov_ssse3; extern const struct raid6_recov_calls raid6_recov_avx2; +extern const struct raid6_calls raid6_neonx1; +extern const struct raid6_calls raid6_neonx2; +extern const struct raid6_calls raid6_neonx4; +extern const struct raid6_calls raid6_neonx8; + /* Algorithm list */ extern const struct raid6_calls * const raid6_algos[]; extern const struct raid6_recov_calls *const raid6_recov_algos[]; diff --git a/include/linux/ramfs.h b/include/linux/ramfs.h index 5bf5500db83d..753207c8ce20 100644 --- a/include/linux/ramfs.h +++ b/include/linux/ramfs.h @@ -6,7 +6,13 @@ struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir, extern struct dentry *ramfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data); -#ifndef CONFIG_MMU +#ifdef CONFIG_MMU +static inline int +ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) +{ + return 0; +} +#else extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize); extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file, unsigned long addr, @@ -19,7 +25,7 @@ extern int ramfs_nommu_mmap(struct file *file, struct vm_area_struct *vma); extern const struct file_operations ramfs_file_operations; extern const struct vm_operations_struct generic_file_vm_ops; -extern int __init init_rootfs(void); +extern int __init init_ramfs_fs(void); int ramfs_fill_super(struct super_block *sb, void *data, int silent); diff --git a/include/linux/random.h b/include/linux/random.h index 347ce553a306..6312dd9ba449 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -17,6 +17,7 @@ extern void add_interrupt_randomness(int irq, int irq_flags); extern void get_random_bytes(void *buf, int nbytes); extern void get_random_bytes_arch(void *buf, int nbytes); void generate_random_uuid(unsigned char uuid_out[16]); +extern int random_int_secret_init(void); #ifndef MODULE extern const struct file_operations random_fops, urandom_fops; @@ -29,13 +30,6 @@ u32 prandom_u32(void); void prandom_bytes(void *buf, int nbytes); void prandom_seed(u32 seed); -/* - * These macros are preserved for backward compatibility and should be - * removed as soon as a transition is finished. - */ -#define random32() prandom_u32() -#define srandom32(seed) prandom_seed(seed) - u32 prandom_u32_state(struct rnd_state *); void prandom_bytes_state(struct rnd_state *state, void *buf, int nbytes); diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index 0022c1bb1e26..aa870a4ddf54 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h @@ -68,6 +68,10 @@ extern struct rb_node *rb_prev(const struct rb_node *); extern struct rb_node *rb_first(const struct rb_root *); extern struct rb_node *rb_last(const struct rb_root *); +/* Postorder iteration - always visit the parent after its children */ +extern struct rb_node *rb_first_postorder(const struct rb_root *); +extern struct rb_node *rb_next_postorder(const struct rb_node *); + /* Fast replacement of a single node without remove/rebalance/add/rebalance */ extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); @@ -81,4 +85,22 @@ static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, *rb_link = node; } +/** + * rbtree_postorder_for_each_entry_safe - iterate over rb_root in post order of + * given type safe against removal of rb_node entry + * + * @pos: the 'type *' to use as a loop cursor. + * @n: another 'type *' to use as temporary storage + * @root: 'rb_root *' of the rbtree. + * @field: the name of the rb_node field within 'type'. + */ +#define rbtree_postorder_for_each_entry_safe(pos, n, root, field) \ + for (pos = rb_entry(rb_first_postorder(root), typeof(*pos), field),\ + n = rb_entry(rb_next_postorder(&pos->field), \ + typeof(*pos), field); \ + &pos->field; \ + pos = n, \ + n = rb_entry(rb_next_postorder(&pos->field), \ + typeof(*pos), field)) + #endif /* _LINUX_RBTREE_H */ diff --git a/include/linux/rculist.h b/include/linux/rculist.h index 8089e35d47ac..45a0a9e81478 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -19,6 +19,21 @@ */ /* + * INIT_LIST_HEAD_RCU - Initialize a list_head visible to RCU readers + * @list: list to be initialized + * + * You should instead use INIT_LIST_HEAD() for normal initialization and + * cleanup tasks, when readers have no access to the list being initialized. + * However, if the list being initialized is visible to readers, you + * need to keep the compiler from being too mischievous. + */ +static inline void INIT_LIST_HEAD_RCU(struct list_head *list) +{ + ACCESS_ONCE(list->next) = list; + ACCESS_ONCE(list->prev) = list; +} + +/* * return the ->next pointer of a list_head in an rcu safe * way, we must not access it directly */ @@ -191,9 +206,13 @@ static inline void list_splice_init_rcu(struct list_head *list, if (list_empty(list)) return; - /* "first" and "last" tracking list, so initialize it. */ + /* + * "first" and "last" tracking list, so initialize it. RCU readers + * have access to this list, so we must use INIT_LIST_HEAD_RCU() + * instead of INIT_LIST_HEAD(). + */ - INIT_LIST_HEAD(list); + INIT_LIST_HEAD_RCU(list); /* * At this point, the list body still points to the source list. @@ -267,8 +286,9 @@ static inline void list_splice_init_rcu(struct list_head *list, */ #define list_first_or_null_rcu(ptr, type, member) \ ({struct list_head *__ptr = (ptr); \ - struct list_head __rcu *__next = list_next_rcu(__ptr); \ - likely(__ptr != __next) ? container_of(__next, type, member) : NULL; \ + struct list_head *__next = ACCESS_ONCE(__ptr->next); \ + likely(__ptr != __next) ? \ + list_entry_rcu(__next, type, member) : NULL; \ }) /** @@ -461,6 +481,26 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, &(pos)->member)), typeof(*(pos)), member)) /** + * hlist_for_each_entry_rcu_notrace - iterate over rcu list of given type (for tracing) + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + * + * This list-traversal primitive may safely run concurrently with + * the _rcu list-mutation primitives such as hlist_add_head_rcu() + * as long as the traversal is guarded by rcu_read_lock(). + * + * This is the same as hlist_for_each_entry_rcu() except that it does + * not do any RCU debugging or tracing. + */ +#define hlist_for_each_entry_rcu_notrace(pos, head, member) \ + for (pos = hlist_entry_safe (rcu_dereference_raw_notrace(hlist_first_rcu(head)),\ + typeof(*(pos)), member); \ + pos; \ + pos = hlist_entry_safe(rcu_dereference_raw_notrace(hlist_next_rcu(\ + &(pos)->member)), typeof(*(pos)), member)) + +/** * hlist_for_each_entry_rcu_bh - iterate over rcu list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. diff --git a/include/linux/rculist_bl.h b/include/linux/rculist_bl.h index cf1244fbf3b6..4f216c59e7db 100644 --- a/include/linux/rculist_bl.h +++ b/include/linux/rculist_bl.h @@ -20,7 +20,7 @@ static inline void hlist_bl_set_first_rcu(struct hlist_bl_head *h, static inline struct hlist_bl_node *hlist_bl_first_rcu(struct hlist_bl_head *h) { return (struct hlist_bl_node *) - ((unsigned long)rcu_dereference(h->first) & ~LIST_BL_LOCKMASK); + ((unsigned long)rcu_dereference_check(h->first, hlist_bl_is_locked(h)) & ~LIST_BL_LOCKMASK); } /** diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h index 2ae13714828b..1c33dd7da4a7 100644 --- a/include/linux/rculist_nulls.h +++ b/include/linux/rculist_nulls.h @@ -105,9 +105,14 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n, * @head: the head for your list. * @member: the name of the hlist_nulls_node within the struct. * + * The barrier() is needed to make sure compiler doesn't cache first element [1], + * as this loop can be restarted [2] + * [1] Documentation/atomic_ops.txt around line 114 + * [2] Documentation/RCU/rculist_nulls.txt around line 146 */ #define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) \ - for (pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ + for (({barrier();}), \ + pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ (!is_a_nulls(pos)) && \ ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \ pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos))) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index b758ce17b309..69d8d7211de8 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -52,7 +52,7 @@ extern int rcutorture_runnable; /* for sysctl */ #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) extern void rcutorture_record_test_transition(void); extern void rcutorture_record_progress(unsigned long vernum); -extern void do_trace_rcu_torture_read(char *rcutorturename, +extern void do_trace_rcu_torture_read(const char *rcutorturename, struct rcu_head *rhp, unsigned long secs, unsigned long c_old, @@ -65,7 +65,7 @@ static inline void rcutorture_record_progress(unsigned long vernum) { } #ifdef CONFIG_RCU_TRACE -extern void do_trace_rcu_torture_read(char *rcutorturename, +extern void do_trace_rcu_torture_read(const char *rcutorturename, struct rcu_head *rhp, unsigned long secs, unsigned long c_old, @@ -80,6 +80,7 @@ extern void do_trace_rcu_torture_read(char *rcutorturename, #define UINT_CMP_LT(a, b) (UINT_MAX / 2 < (a) - (b)) #define ULONG_CMP_GE(a, b) (ULONG_MAX / 2 >= (a) - (b)) #define ULONG_CMP_LT(a, b) (ULONG_MAX / 2 < (a) - (b)) +#define ulong2long(a) (*(long *)(&(a))) /* Exported common interfaces */ @@ -215,6 +216,7 @@ static inline int rcu_preempt_depth(void) #endif /* #else #ifdef CONFIG_PREEMPT_RCU */ /* Internal to kernel */ +extern void rcu_init(void); extern void rcu_sched_qs(int cpu); extern void rcu_bh_qs(int cpu); extern void rcu_check_callbacks(int cpu, int user); @@ -227,19 +229,13 @@ extern void rcu_irq_exit(void); #ifdef CONFIG_RCU_USER_QS extern void rcu_user_enter(void); extern void rcu_user_exit(void); -extern void rcu_user_enter_after_irq(void); -extern void rcu_user_exit_after_irq(void); #else static inline void rcu_user_enter(void) { } static inline void rcu_user_exit(void) { } -static inline void rcu_user_enter_after_irq(void) { } -static inline void rcu_user_exit_after_irq(void) { } static inline void rcu_user_hooks_switch(struct task_struct *prev, struct task_struct *next) { } #endif /* CONFIG_RCU_USER_QS */ -extern void exit_rcu(void); - /** * RCU_NONIDLE - Indicate idle-loop code that needs RCU readers * @a: Code that RCU needs to pay attention to. @@ -265,6 +261,10 @@ extern void exit_rcu(void); rcu_irq_exit(); \ } while (0) +#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) || defined(CONFIG_SMP) +extern bool __rcu_is_watching(void); +#endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) || defined(CONFIG_SMP) */ + /* * Infrastructure to implement the synchronize_() primitives in * TREE_RCU and rcu_barrier_() primitives in TINY_RCU. @@ -276,7 +276,7 @@ void wait_rcu_gp(call_rcu_func_t crf); #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU) #include <linux/rcutree.h> -#elif defined(CONFIG_TINY_RCU) || defined(CONFIG_TINY_PREEMPT_RCU) +#elif defined(CONFIG_TINY_RCU) #include <linux/rcutiny.h> #else #error "Unknown RCU implementation specified to kernel configuration" @@ -301,10 +301,6 @@ static inline void destroy_rcu_head_on_stack(struct rcu_head *head) } #endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ -#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SMP) -extern int rcu_is_cpu_idle(void); -#endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SMP) */ - #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) bool rcu_lockdep_current_cpu_online(void); #else /* #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) */ @@ -355,7 +351,7 @@ static inline int rcu_read_lock_held(void) { if (!debug_lockdep_rcu_enabled()) return 1; - if (rcu_is_cpu_idle()) + if (!rcu_is_watching()) return 0; if (!rcu_lockdep_current_cpu_online()) return 0; @@ -406,7 +402,7 @@ static inline int rcu_read_lock_sched_held(void) if (!debug_lockdep_rcu_enabled()) return 1; - if (rcu_is_cpu_idle()) + if (!rcu_is_watching()) return 0; if (!rcu_lockdep_current_cpu_online()) return 0; @@ -510,8 +506,17 @@ static inline void rcu_preempt_sleep_check(void) #ifdef __CHECKER__ #define rcu_dereference_sparse(p, space) \ ((void)(((typeof(*p) space *)p) == p)) +/* The dummy first argument in __rcu_assign_pointer_typecheck makes the + * typechecked pointer the second argument, matching rcu_assign_pointer itself; + * this avoids confusion about argument numbers in warning messages. */ +#define __rcu_assign_pointer_check_kernel(v) \ + do { \ + extern void __rcu_assign_pointer_typecheck(int, typeof(*(v)) __kernel *); \ + __rcu_assign_pointer_typecheck(0, v); \ + } while (0) #else /* #ifdef __CHECKER__ */ #define rcu_dereference_sparse(p, space) +#define __rcu_assign_pointer_check_kernel(v) do { } while (0) #endif /* #else #ifdef __CHECKER__ */ #define __rcu_access_pointer(p, space) \ @@ -555,7 +560,8 @@ static inline void rcu_preempt_sleep_check(void) #define __rcu_assign_pointer(p, v, space) \ do { \ smp_wmb(); \ - (p) = (typeof(*v) __force space *)(v); \ + __rcu_assign_pointer_check_kernel(v); \ + ACCESS_ONCE(p) = (typeof(*(v)) __force space *)(v); \ } while (0) @@ -639,6 +645,15 @@ static inline void rcu_preempt_sleep_check(void) #define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/ +/* + * The tracing infrastructure traces RCU (we want that), but unfortunately + * some of the RCU checks causes tracing to lock up the system. + * + * The tracing version of rcu_dereference_raw() must not call + * rcu_read_lock_held(). + */ +#define rcu_dereference_raw_notrace(p) __rcu_dereference_check((p), 1, __rcu) + /** * rcu_access_index() - fetch RCU index with no dereferencing * @p: The index to read @@ -766,7 +781,7 @@ static inline void rcu_read_lock(void) __rcu_read_lock(); __acquire(RCU); rcu_lock_acquire(&rcu_lock_map); - rcu_lockdep_assert(!rcu_is_cpu_idle(), + rcu_lockdep_assert(rcu_is_watching(), "rcu_read_lock() used illegally while idle"); } @@ -787,7 +802,7 @@ static inline void rcu_read_lock(void) */ static inline void rcu_read_unlock(void) { - rcu_lockdep_assert(!rcu_is_cpu_idle(), + rcu_lockdep_assert(rcu_is_watching(), "rcu_read_unlock() used illegally while idle"); rcu_lock_release(&rcu_lock_map); __release(RCU); @@ -816,7 +831,7 @@ static inline void rcu_read_lock_bh(void) local_bh_disable(); __acquire(RCU_BH); rcu_lock_acquire(&rcu_bh_lock_map); - rcu_lockdep_assert(!rcu_is_cpu_idle(), + rcu_lockdep_assert(rcu_is_watching(), "rcu_read_lock_bh() used illegally while idle"); } @@ -827,7 +842,7 @@ static inline void rcu_read_lock_bh(void) */ static inline void rcu_read_unlock_bh(void) { - rcu_lockdep_assert(!rcu_is_cpu_idle(), + rcu_lockdep_assert(rcu_is_watching(), "rcu_read_unlock_bh() used illegally while idle"); rcu_lock_release(&rcu_bh_lock_map); __release(RCU_BH); @@ -852,7 +867,7 @@ static inline void rcu_read_lock_sched(void) preempt_disable(); __acquire(RCU_SCHED); rcu_lock_acquire(&rcu_sched_lock_map); - rcu_lockdep_assert(!rcu_is_cpu_idle(), + rcu_lockdep_assert(rcu_is_watching(), "rcu_read_lock_sched() used illegally while idle"); } @@ -870,7 +885,7 @@ static inline notrace void rcu_read_lock_sched_notrace(void) */ static inline void rcu_read_unlock_sched(void) { - rcu_lockdep_assert(!rcu_is_cpu_idle(), + rcu_lockdep_assert(rcu_is_watching(), "rcu_read_unlock_sched() used illegally while idle"); rcu_lock_release(&rcu_sched_lock_map); __release(RCU_SCHED); @@ -999,4 +1014,29 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) #define kfree_rcu(ptr, rcu_head) \ __kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head)) +#ifdef CONFIG_RCU_NOCB_CPU +extern bool rcu_is_nocb_cpu(int cpu); +#else +static inline bool rcu_is_nocb_cpu(int cpu) { return false; } +#endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */ + + +/* Only for use by adaptive-ticks code. */ +#ifdef CONFIG_NO_HZ_FULL_SYSIDLE +extern bool rcu_sys_is_idle(void); +extern void rcu_sysidle_force_exit(void); +#else /* #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */ + +static inline bool rcu_sys_is_idle(void) +{ + return false; +} + +static inline void rcu_sysidle_force_exit(void) +{ +} + +#endif /* #else #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */ + + #endif /* __LINUX_RCUPDATE_H */ diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h index 4e56a9c69a35..09ebcbe9fd78 100644 --- a/include/linux/rcutiny.h +++ b/include/linux/rcutiny.h @@ -27,10 +27,6 @@ #include <linux/cache.h> -static inline void rcu_init(void) -{ -} - static inline void rcu_barrier_bh(void) { wait_rcu_gp(call_rcu_bh); @@ -41,8 +37,6 @@ static inline void rcu_barrier_sched(void) wait_rcu_gp(call_rcu_sched); } -#ifdef CONFIG_TINY_RCU - static inline void synchronize_rcu_expedited(void) { synchronize_sched(); /* Only one CPU, so pretty fast anyway!!! */ @@ -53,17 +47,6 @@ static inline void rcu_barrier(void) rcu_barrier_sched(); /* Only one CPU, so only one list of callbacks! */ } -#else /* #ifdef CONFIG_TINY_RCU */ - -void synchronize_rcu_expedited(void); - -static inline void rcu_barrier(void) -{ - wait_rcu_gp(call_rcu); -} - -#endif /* #else #ifdef CONFIG_TINY_RCU */ - static inline void synchronize_rcu_bh(void) { synchronize_sched(); @@ -85,35 +68,15 @@ static inline void kfree_call_rcu(struct rcu_head *head, call_rcu(head, func); } -#ifdef CONFIG_TINY_RCU - -static inline void rcu_preempt_note_context_switch(void) -{ -} - static inline int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies) { *delta_jiffies = ULONG_MAX; return 0; } -#else /* #ifdef CONFIG_TINY_RCU */ - -void rcu_preempt_note_context_switch(void); -int rcu_preempt_needs_cpu(void); - -static inline int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies) -{ - *delta_jiffies = ULONG_MAX; - return rcu_preempt_needs_cpu(); -} - -#endif /* #else #ifdef CONFIG_TINY_RCU */ - static inline void rcu_note_context_switch(int cpu) { rcu_sched_qs(cpu); - rcu_preempt_note_context_switch(); } /* @@ -156,6 +119,10 @@ static inline void rcu_cpu_stall_reset(void) { } +static inline void exit_rcu(void) +{ +} + #ifdef CONFIG_DEBUG_LOCK_ALLOC extern int rcu_scheduler_active __read_mostly; extern void rcu_scheduler_starting(void); @@ -165,4 +132,21 @@ static inline void rcu_scheduler_starting(void) } #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ +#if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) + +static inline bool rcu_is_watching(void) +{ + return __rcu_is_watching(); +} + +#else /* defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) */ + +static inline bool rcu_is_watching(void) +{ + return true; +} + + +#endif /* #else defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE) */ + #endif /* __LINUX_RCUTINY_H */ diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index 952b79339304..4b9c81548742 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h @@ -30,7 +30,6 @@ #ifndef __LINUX_RCUTREE_H #define __LINUX_RCUTREE_H -extern void rcu_init(void); extern void rcu_note_context_switch(int cpu); extern int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies); extern void rcu_cpu_stall_reset(void); @@ -86,7 +85,11 @@ extern void rcu_force_quiescent_state(void); extern void rcu_bh_force_quiescent_state(void); extern void rcu_sched_force_quiescent_state(void); +extern void exit_rcu(void); + extern void rcu_scheduler_starting(void); extern int rcu_scheduler_active __read_mostly; +extern bool rcu_is_watching(void); + #endif /* __LINUX_RCUTREE_H */ diff --git a/include/linux/reboot.h b/include/linux/reboot.h index 23b36304cd88..8e00f9f6f963 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h @@ -10,6 +10,31 @@ #define SYS_HALT 0x0002 /* Notify of system halt */ #define SYS_POWER_OFF 0x0003 /* Notify of system power off */ +enum reboot_mode { + REBOOT_COLD = 0, + REBOOT_WARM, + REBOOT_HARD, + REBOOT_SOFT, + REBOOT_GPIO, +}; +extern enum reboot_mode reboot_mode; + +enum reboot_type { + BOOT_TRIPLE = 't', + BOOT_KBD = 'k', + BOOT_BIOS = 'b', + BOOT_ACPI = 'a', + BOOT_EFI = 'e', + BOOT_CF9 = 'p', + BOOT_CF9_COND = 'q', +}; +extern enum reboot_type reboot_type; + +extern int reboot_default; +extern int reboot_cpu; +extern int reboot_force; + + extern int register_reboot_notifier(struct notifier_block *); extern int unregister_reboot_notifier(struct notifier_block *); @@ -26,7 +51,7 @@ extern void machine_shutdown(void); struct pt_regs; extern void machine_crash_shutdown(struct pt_regs *); -/* +/* * Architecture independent implemenations of sys_reboot commands. */ diff --git a/include/linux/regmap.h b/include/linux/regmap.h index bf77dfdabef9..24e993636db0 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -15,6 +15,8 @@ #include <linux/list.h> #include <linux/rbtree.h> +#include <linux/err.h> +#include <linux/bug.h> struct module; struct device; @@ -23,6 +25,7 @@ struct irq_domain; struct spi_device; struct regmap; struct regmap_range_cfg; +struct regmap_field; /* An enum of all the supported cache types */ enum regcache_type { @@ -67,6 +70,8 @@ struct regmap_range { unsigned int range_max; }; +#define regmap_reg_range(low, high) { .range_min = low, .range_max = high, } + /* * A table of ranges including some yes ranges and some no ranges. * If a register belongs to a no_range, the corresponding check function @@ -389,14 +394,20 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, bool *change); int regmap_get_val_bytes(struct regmap *map); int regmap_async_complete(struct regmap *map); +bool regmap_can_raw_write(struct regmap *map); int regcache_sync(struct regmap *map); int regcache_sync_region(struct regmap *map, unsigned int min, unsigned int max); +int regcache_drop_region(struct regmap *map, unsigned int min, + unsigned int max); void regcache_cache_only(struct regmap *map, bool enable); void regcache_cache_bypass(struct regmap *map, bool enable); void regcache_mark_dirty(struct regmap *map); +bool regmap_check_range_table(struct regmap *map, unsigned int reg, + const struct regmap_access_table *table); + int regmap_register_patch(struct regmap *map, const struct reg_default *regs, int num_regs); @@ -411,6 +422,49 @@ bool regmap_reg_in_ranges(unsigned int reg, unsigned int nranges); /** + * Description of an register field + * + * @reg: Offset of the register within the regmap bank + * @lsb: lsb of the register field. + * @reg: msb of the register field. + * @id_size: port size if it has some ports + * @id_offset: address offset for each ports + */ +struct reg_field { + unsigned int reg; + unsigned int lsb; + unsigned int msb; + unsigned int id_size; + unsigned int id_offset; +}; + +#define REG_FIELD(_reg, _lsb, _msb) { \ + .reg = _reg, \ + .lsb = _lsb, \ + .msb = _msb, \ + } + +struct regmap_field *regmap_field_alloc(struct regmap *regmap, + struct reg_field reg_field); +void regmap_field_free(struct regmap_field *field); + +struct regmap_field *devm_regmap_field_alloc(struct device *dev, + struct regmap *regmap, struct reg_field reg_field); +void devm_regmap_field_free(struct device *dev, struct regmap_field *field); + +int regmap_field_read(struct regmap_field *field, unsigned int *val); +int regmap_field_write(struct regmap_field *field, unsigned int val); +int regmap_field_update_bits(struct regmap_field *field, + unsigned int mask, unsigned int val); + +int regmap_fields_write(struct regmap_field *field, unsigned int id, + unsigned int val); +int regmap_fields_read(struct regmap_field *field, unsigned int id, + unsigned int *val); +int regmap_fields_update_bits(struct regmap_field *field, unsigned int id, + unsigned int mask, unsigned int val); + +/** * Description of an IRQ for the generic regmap irq_chip. * * @reg_offset: Offset of the status/mask register within the bank @@ -433,6 +487,9 @@ struct regmap_irq { * @ack_base: Base ack address. If zero then the chip is clear on read. * @wake_base: Base address for wake enables. If zero unsupported. * @irq_reg_stride: Stride to use for chips where registers are not contiguous. + * @init_ack_masked: Ack all masked interrupts once during initalization. + * @mask_invert: Inverted mask register: cleared bits are masked out. + * @wake_invert: Inverted wake register: cleared bits are wake enabled. * @runtime_pm: Hold a runtime PM lock on the device when accessing it. * * @num_regs: Number of registers in each control bank. @@ -448,9 +505,10 @@ struct regmap_irq_chip { unsigned int ack_base; unsigned int wake_base; unsigned int irq_reg_stride; - unsigned int mask_invert; - unsigned int wake_invert; - bool runtime_pm; + bool init_ack_masked:1; + bool mask_invert:1; + bool wake_invert:1; + bool runtime_pm:1; int num_regs; @@ -561,6 +619,13 @@ static inline int regcache_sync_region(struct regmap *map, unsigned int min, return -EINVAL; } +static inline int regcache_drop_region(struct regmap *map, unsigned int min, + unsigned int max) +{ + WARN_ONCE(1, "regmap API is disabled"); + return -EINVAL; +} + static inline void regcache_cache_only(struct regmap *map, bool enable) { WARN_ONCE(1, "regmap API is disabled"); diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 7bd73bbdfd1b..75307447cef9 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -5,11 +5,14 @@ * * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson + * Daniel Willerud <daniel.willerud@stericsson.com> for ST-Ericsson */ #ifndef __LINUX_MFD_AB8500_REGULATOR_H #define __LINUX_MFD_AB8500_REGULATOR_H +#include <linux/platform_device.h> + /* AB8500 regulators */ enum ab8500_regulator_id { AB8500_LDO_AUX1, @@ -17,7 +20,6 @@ enum ab8500_regulator_id { AB8500_LDO_AUX3, AB8500_LDO_INTCORE, AB8500_LDO_TVOUT, - AB8500_LDO_USB, AB8500_LDO_AUDIO, AB8500_LDO_ANAMIC1, AB8500_LDO_ANAMIC2, @@ -26,7 +28,28 @@ enum ab8500_regulator_id { AB8500_NUM_REGULATORS, }; -/* AB9450 regulators */ +/* AB8505 regulators */ +enum ab8505_regulator_id { + AB8505_LDO_AUX1, + AB8505_LDO_AUX2, + AB8505_LDO_AUX3, + AB8505_LDO_AUX4, + AB8505_LDO_AUX5, + AB8505_LDO_AUX6, + AB8505_LDO_INTCORE, + AB8505_LDO_ADC, + AB8505_LDO_USB, + AB8505_LDO_AUDIO, + AB8505_LDO_ANAMIC1, + AB8505_LDO_ANAMIC2, + AB8505_LDO_AUX8, + AB8505_LDO_ANA, + AB8505_SYSCLKREQ_2, + AB8505_SYSCLKREQ_4, + AB8505_NUM_REGULATORS, +}; + +/* AB9540 regulators */ enum ab9540_regulator_id { AB9540_LDO_AUX1, AB9540_LDO_AUX2, @@ -45,16 +68,39 @@ enum ab9540_regulator_id { AB9540_NUM_REGULATORS, }; -/* AB8500 and AB9540 register initialization */ +/* AB8540 regulators */ +enum ab8540_regulator_id { + AB8540_LDO_AUX1, + AB8540_LDO_AUX2, + AB8540_LDO_AUX3, + AB8540_LDO_AUX4, + AB8540_LDO_AUX5, + AB8540_LDO_AUX6, + AB8540_LDO_INTCORE, + AB8540_LDO_TVOUT, + AB8540_LDO_AUDIO, + AB8540_LDO_ANAMIC1, + AB8540_LDO_ANAMIC2, + AB8540_LDO_DMIC, + AB8540_LDO_ANA, + AB8540_LDO_SDIO, + AB8540_SYSCLKREQ_2, + AB8540_SYSCLKREQ_4, + AB8540_NUM_REGULATORS, +}; + +/* AB8500, AB8505, and AB9540 register initialization */ struct ab8500_regulator_reg_init { int id; + u8 mask; u8 value; }; -#define INIT_REGULATOR_REGISTER(_id, _value) \ - { \ - .id = _id, \ - .value = _value, \ +#define INIT_REGULATOR_REGISTER(_id, _mask, _value) \ + { \ + .id = _id, \ + .mask = _mask, \ + .value = _value, \ } /* AB8500 registers */ @@ -86,10 +132,58 @@ enum ab8500_regulator_reg { AB8500_REGUCTRL2SPARE, AB8500_REGUCTRLDISCH, AB8500_REGUCTRLDISCH2, - AB8500_VSMPS1SEL1, AB8500_NUM_REGULATOR_REGISTERS, }; +/* AB8505 registers */ +enum ab8505_regulator_reg { + AB8505_REGUREQUESTCTRL1, + AB8505_REGUREQUESTCTRL2, + AB8505_REGUREQUESTCTRL3, + AB8505_REGUREQUESTCTRL4, + AB8505_REGUSYSCLKREQ1HPVALID1, + AB8505_REGUSYSCLKREQ1HPVALID2, + AB8505_REGUHWHPREQ1VALID1, + AB8505_REGUHWHPREQ1VALID2, + AB8505_REGUHWHPREQ2VALID1, + AB8505_REGUHWHPREQ2VALID2, + AB8505_REGUSWHPREQVALID1, + AB8505_REGUSWHPREQVALID2, + AB8505_REGUSYSCLKREQVALID1, + AB8505_REGUSYSCLKREQVALID2, + AB8505_REGUVAUX4REQVALID, + AB8505_REGUMISC1, + AB8505_VAUDIOSUPPLY, + AB8505_REGUCTRL1VAMIC, + AB8505_VSMPSAREGU, + AB8505_VSMPSBREGU, + AB8505_VSAFEREGU, /* NOTE! PRCMU register */ + AB8505_VPLLVANAREGU, + AB8505_EXTSUPPLYREGU, + AB8505_VAUX12REGU, + AB8505_VRF1VAUX3REGU, + AB8505_VSMPSASEL1, + AB8505_VSMPSASEL2, + AB8505_VSMPSASEL3, + AB8505_VSMPSBSEL1, + AB8505_VSMPSBSEL2, + AB8505_VSMPSBSEL3, + AB8505_VSAFESEL1, /* NOTE! PRCMU register */ + AB8505_VSAFESEL2, /* NOTE! PRCMU register */ + AB8505_VSAFESEL3, /* NOTE! PRCMU register */ + AB8505_VAUX1SEL, + AB8505_VAUX2SEL, + AB8505_VRF1VAUX3SEL, + AB8505_VAUX4REQCTRL, + AB8505_VAUX4REGU, + AB8505_VAUX4SEL, + AB8505_REGUCTRLDISCH, + AB8505_REGUCTRLDISCH2, + AB8505_REGUCTRLDISCH3, + AB8505_CTRLVAUX5, + AB8505_CTRLVAUX6, + AB8505_NUM_REGULATOR_REGISTERS, +}; /* AB9540 registers */ enum ab9540_regulator_reg { @@ -139,4 +233,107 @@ enum ab9540_regulator_reg { AB9540_NUM_REGULATOR_REGISTERS, }; +/* AB8540 registers */ +enum ab8540_regulator_reg { + AB8540_REGUREQUESTCTRL1, + AB8540_REGUREQUESTCTRL2, + AB8540_REGUREQUESTCTRL3, + AB8540_REGUREQUESTCTRL4, + AB8540_REGUSYSCLKREQ1HPVALID1, + AB8540_REGUSYSCLKREQ1HPVALID2, + AB8540_REGUHWHPREQ1VALID1, + AB8540_REGUHWHPREQ1VALID2, + AB8540_REGUHWHPREQ2VALID1, + AB8540_REGUHWHPREQ2VALID2, + AB8540_REGUSWHPREQVALID1, + AB8540_REGUSWHPREQVALID2, + AB8540_REGUSYSCLKREQVALID1, + AB8540_REGUSYSCLKREQVALID2, + AB8540_REGUVAUX4REQVALID, + AB8540_REGUVAUX5REQVALID, + AB8540_REGUVAUX6REQVALID, + AB8540_REGUVCLKBREQVALID, + AB8540_REGUVRF1REQVALID, + AB8540_REGUMISC1, + AB8540_VAUDIOSUPPLY, + AB8540_REGUCTRL1VAMIC, + AB8540_VHSIC, + AB8540_VSDIO, + AB8540_VSMPS1REGU, + AB8540_VSMPS2REGU, + AB8540_VSMPS3REGU, + AB8540_VPLLVANAREGU, + AB8540_EXTSUPPLYREGU, + AB8540_VAUX12REGU, + AB8540_VRF1VAUX3REGU, + AB8540_VSMPS1SEL1, + AB8540_VSMPS1SEL2, + AB8540_VSMPS1SEL3, + AB8540_VSMPS2SEL1, + AB8540_VSMPS2SEL2, + AB8540_VSMPS2SEL3, + AB8540_VSMPS3SEL1, + AB8540_VSMPS3SEL2, + AB8540_VAUX1SEL, + AB8540_VAUX2SEL, + AB8540_VRF1VAUX3SEL, + AB8540_REGUCTRL2SPARE, + AB8540_VAUX4REQCTRL, + AB8540_VAUX4REGU, + AB8540_VAUX4SEL, + AB8540_VAUX5REQCTRL, + AB8540_VAUX5REGU, + AB8540_VAUX5SEL, + AB8540_VAUX6REQCTRL, + AB8540_VAUX6REGU, + AB8540_VAUX6SEL, + AB8540_VCLKBREQCTRL, + AB8540_VCLKBREGU, + AB8540_VCLKBSEL, + AB8540_VRF1REQCTRL, + AB8540_REGUCTRLDISCH, + AB8540_REGUCTRLDISCH2, + AB8540_REGUCTRLDISCH3, + AB8540_REGUCTRLDISCH4, + AB8540_VSIMSYSCLKCTRL, + AB8540_VANAVPLLSEL, + AB8540_NUM_REGULATOR_REGISTERS, +}; + +/* AB8500 external regulators */ +struct ab8500_ext_regulator_cfg { + bool hwreq; /* requires hw mode or high power mode */ +}; + +enum ab8500_ext_regulator_id { + AB8500_EXT_SUPPLY1, + AB8500_EXT_SUPPLY2, + AB8500_EXT_SUPPLY3, + AB8500_NUM_EXT_REGULATORS, +}; + +/* AB8500 regulator platform data */ +struct ab8500_regulator_platform_data { + int num_reg_init; + struct ab8500_regulator_reg_init *reg_init; + int num_regulator; + struct regulator_init_data *regulator; + int num_ext_regulator; + struct regulator_init_data *ext_regulator; +}; + +#ifdef CONFIG_REGULATOR_AB8500_DEBUG +int ab8500_regulator_debug_init(struct platform_device *pdev); +int ab8500_regulator_debug_exit(struct platform_device *pdev); +#else +static inline int ab8500_regulator_debug_init(struct platform_device *pdev) +{ + return 0; +} +static inline int ab8500_regulator_debug_exit(struct platform_device *pdev) +{ + return 0; +} +#endif + #endif diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 7bc732ce6e50..27be915caa96 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -137,22 +137,28 @@ struct regulator *__must_check devm_regulator_get(struct device *dev, const char *id); struct regulator *__must_check regulator_get_exclusive(struct device *dev, const char *id); +struct regulator *__must_check devm_regulator_get_exclusive(struct device *dev, + const char *id); +struct regulator *__must_check regulator_get_optional(struct device *dev, + const char *id); +struct regulator *__must_check devm_regulator_get_optional(struct device *dev, + const char *id); void regulator_put(struct regulator *regulator); void devm_regulator_put(struct regulator *regulator); /* regulator output control and status */ -int regulator_enable(struct regulator *regulator); +int __must_check regulator_enable(struct regulator *regulator); int regulator_disable(struct regulator *regulator); int regulator_force_disable(struct regulator *regulator); int regulator_is_enabled(struct regulator *regulator); int regulator_disable_deferred(struct regulator *regulator, int ms); -int regulator_bulk_get(struct device *dev, int num_consumers, - struct regulator_bulk_data *consumers); -int devm_regulator_bulk_get(struct device *dev, int num_consumers, - struct regulator_bulk_data *consumers); -int regulator_bulk_enable(int num_consumers, - struct regulator_bulk_data *consumers); +int __must_check regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers); +int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers); +int __must_check regulator_bulk_enable(int num_consumers, + struct regulator_bulk_data *consumers); int regulator_bulk_disable(int num_consumers, struct regulator_bulk_data *consumers); int regulator_bulk_force_disable(int num_consumers, @@ -165,6 +171,7 @@ int regulator_count_voltages(struct regulator *regulator); int regulator_list_voltage(struct regulator *regulator, unsigned selector); int regulator_is_supported_voltage(struct regulator *regulator, int min_uV, int max_uV); +unsigned int regulator_get_linear_step(struct regulator *regulator); int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); int regulator_set_voltage_time(struct regulator *regulator, int old_uV, int new_uV); @@ -216,6 +223,25 @@ devm_regulator_get(struct device *dev, const char *id) return NULL; } +static inline struct regulator *__must_check +regulator_get_exclusive(struct device *dev, const char *id) +{ + return NULL; +} + +static inline struct regulator *__must_check +regulator_get_optional(struct device *dev, const char *id) +{ + return NULL; +} + + +static inline struct regulator *__must_check +devm_regulator_get_optional(struct device *dev, const char *id) +{ + return NULL; +} + static inline void regulator_put(struct regulator *regulator) { } @@ -368,8 +394,11 @@ static inline int regulator_count_voltages(struct regulator *regulator) static inline int regulator_set_voltage_tol(struct regulator *regulator, int new_uV, int tol_uV) { - return regulator_set_voltage(regulator, - new_uV - tol_uV, new_uV + tol_uV); + if (regulator_set_voltage(regulator, new_uV, new_uV + tol_uV) == 0) + return 0; + else + return regulator_set_voltage(regulator, + new_uV - tol_uV, new_uV + tol_uV); } static inline int regulator_is_supported_voltage_tol(struct regulator *regulator, diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 23070fd83872..c8b492c6b6a8 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -22,6 +22,7 @@ struct regmap; struct regulator_dev; struct regulator_init_data; +struct regulator_enable_gpio; enum regulator_status { REGULATOR_STATUS_OFF, @@ -39,6 +40,26 @@ enum regulator_status { }; /** + * struct regulator_linear_range - specify linear voltage ranges + * + * Specify a range of voltages for regulator_map_linar_range() and + * regulator_list_linear_range(). + * + * @min_uV: Lowest voltage in range + * @max_uV: Highest voltage in range + * @min_sel: Lowest selector for range + * @max_sel: Highest selector for range + * @uV_step: Step size + */ +struct regulator_linear_range { + unsigned int min_uV; + unsigned int max_uV; + unsigned int min_sel; + unsigned int max_sel; + unsigned int uV_step; +}; + +/** * struct regulator_ops - regulator operations. * * @enable: Configure the regulator as enabled. @@ -188,6 +209,7 @@ enum regulator_type { * @min_uV: Voltage given by the lowest selector (if linear mapping) * @uV_step: Voltage increase with each selector (if linear mapping) * @linear_min_sel: Minimal selector for starting linear mapping + * @fixed_uV: Fixed voltage of rails. * @ramp_delay: Time to settle down after voltage change (unit: uV/us) * @volt_table: Voltage mapping table (if table based mapping) * @@ -199,6 +221,10 @@ enum regulator_type { * output when using regulator_set_voltage_sel_regmap * @enable_reg: Register for control when using regmap enable/disable ops * @enable_mask: Mask for control when using regmap enable/disable ops + * @enable_is_inverted: A flag to indicate set enable_mask bits to disable + * when using regulator_enable_regmap and friends APIs. + * @bypass_reg: Register for control when using regmap set_bypass + * @bypass_mask: Mask for control when using regmap set_bypass * * @enable_time: Time taken for initial enable of regulator (in uS). */ @@ -216,8 +242,12 @@ struct regulator_desc { unsigned int min_uV; unsigned int uV_step; unsigned int linear_min_sel; + int fixed_uV; unsigned int ramp_delay; + const struct regulator_linear_range *linear_ranges; + int n_linear_ranges; + const unsigned int *volt_table; unsigned int vsel_reg; @@ -226,6 +256,7 @@ struct regulator_desc { unsigned int apply_bit; unsigned int enable_reg; unsigned int enable_mask; + bool enable_is_inverted; unsigned int bypass_reg; unsigned int bypass_mask; @@ -300,15 +331,19 @@ struct regulator_dev { struct dentry *debugfs; - int ena_gpio; - unsigned int ena_gpio_invert:1; + struct regulator_enable_gpio *ena_pin; unsigned int ena_gpio_state:1; }; struct regulator_dev * regulator_register(const struct regulator_desc *regulator_desc, const struct regulator_config *config); +struct regulator_dev * +devm_regulator_register(struct device *dev, + const struct regulator_desc *regulator_desc, + const struct regulator_config *config); void regulator_unregister(struct regulator_dev *rdev); +void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev); int regulator_notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data); @@ -321,12 +356,18 @@ int regulator_mode_to_status(unsigned int); int regulator_list_voltage_linear(struct regulator_dev *rdev, unsigned int selector); +int regulator_list_voltage_linear_range(struct regulator_dev *rdev, + unsigned int selector); int regulator_list_voltage_table(struct regulator_dev *rdev, unsigned int selector); int regulator_map_voltage_linear(struct regulator_dev *rdev, int min_uV, int max_uV); +int regulator_map_voltage_linear_range(struct regulator_dev *rdev, + int min_uV, int max_uV); int regulator_map_voltage_iterate(struct regulator_dev *rdev, int min_uV, int max_uV); +int regulator_map_voltage_ascend(struct regulator_dev *rdev, + int min_uV, int max_uV); int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev); int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel); int regulator_is_enabled_regmap(struct regulator_dev *rdev); diff --git a/include/linux/regulator/fan53555.h b/include/linux/regulator/fan53555.h index 5c45c85d52ca..f13880e84d85 100644 --- a/include/linux/regulator/fan53555.h +++ b/include/linux/regulator/fan53555.h @@ -11,6 +11,7 @@ */ #ifndef __FAN53555_H__ +#define __FAN53555_H__ /* VSEL ID */ enum { diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 36adbc82de6a..730e638c5589 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -95,6 +95,7 @@ struct regulator_state { * @initial_state: Suspend state to set by default. * @initial_mode: Mode to set at startup. * @ramp_delay: Time to settle down after voltage change (unit: uV/us) + * @enable_time: Turn-on time of the rails (unit: microseconds) */ struct regulation_constraints { @@ -129,11 +130,13 @@ struct regulation_constraints { unsigned int initial_mode; unsigned int ramp_delay; + unsigned int enable_time; /* constraint flags */ unsigned always_on:1; /* regulator never off when system is on */ unsigned boot_on:1; /* bootloader/firmware enabled regulator */ unsigned apply_uV:1; /* apply uV constraint if min == max */ + unsigned ramp_disable:1; /* disable ramp delay */ }; /** @@ -192,15 +195,10 @@ int regulator_suspend_finish(void); #ifdef CONFIG_REGULATOR void regulator_has_full_constraints(void); -void regulator_use_dummy_regulator(void); #else static inline void regulator_has_full_constraints(void) { } - -static inline void regulator_use_dummy_regulator(void) -{ -} #endif #endif diff --git a/include/linux/regulator/max8660.h b/include/linux/regulator/max8660.h index 9936763621c7..f8a6a4844864 100644 --- a/include/linux/regulator/max8660.h +++ b/include/linux/regulator/max8660.h @@ -39,7 +39,7 @@ enum { */ struct max8660_subdev_data { int id; - char *name; + const char *name; struct regulator_init_data *platform_data; }; diff --git a/include/linux/regulator/max8952.h b/include/linux/regulator/max8952.h index 45e42855ad05..4dbb63a1d4ab 100644 --- a/include/linux/regulator/max8952.h +++ b/include/linux/regulator/max8952.h @@ -122,13 +122,13 @@ struct max8952_platform_data { int gpio_vid1; int gpio_en; - u8 default_mode; - u8 dvs_mode[MAX8952_NUM_DVS_MODE]; /* MAX8952_DVS_MODEx_XXXXmV */ + u32 default_mode; + u32 dvs_mode[MAX8952_NUM_DVS_MODE]; /* MAX8952_DVS_MODEx_XXXXmV */ - u8 sync_freq; - u8 ramp_speed; + u32 sync_freq; + u32 ramp_speed; - struct regulator_init_data reg_data; + struct regulator_init_data *reg_data; }; diff --git a/include/linux/regulator/pfuze100.h b/include/linux/regulator/pfuze100.h new file mode 100644 index 000000000000..65d550bf3954 --- /dev/null +++ b/include/linux/regulator/pfuze100.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef __LINUX_REG_PFUZE100_H +#define __LINUX_REG_PFUZE100_H + +#define PFUZE100_SW1AB 0 +#define PFUZE100_SW1C 1 +#define PFUZE100_SW2 2 +#define PFUZE100_SW3A 3 +#define PFUZE100_SW3B 4 +#define PFUZE100_SW4 5 +#define PFUZE100_SWBST 6 +#define PFUZE100_VSNVS 7 +#define PFUZE100_VREFDDR 8 +#define PFUZE100_VGEN1 9 +#define PFUZE100_VGEN2 10 +#define PFUZE100_VGEN3 11 +#define PFUZE100_VGEN4 12 +#define PFUZE100_VGEN5 13 +#define PFUZE100_VGEN6 14 +#define PFUZE100_MAX_REGULATOR 15 + +struct regulator_init_data; + +struct pfuze_regulator_platform_data { + struct regulator_init_data *init_data[PFUZE100_MAX_REGULATOR]; +}; + +#endif /* __LINUX_REG_PFUZE100_H */ diff --git a/include/linux/relay.h b/include/linux/relay.h index 91cacc34c159..d7c8359693c6 100644 --- a/include/linux/relay.h +++ b/include/linux/relay.h @@ -20,9 +20,6 @@ #include <linux/poll.h> #include <linux/kref.h> -/* Needs a _much_ better name... */ -#define FIX_SIZE(x) ((((x) - 1) & PAGE_MASK) + PAGE_SIZE) - /* * Tracks changes to rchan/rchan_buf structs */ diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index faf33324c78f..9e7e745dac55 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -401,6 +401,9 @@ enum rproc_crash_type { * @crash_comp: completion used to sync crash handler and the rproc reload * @recovery_disabled: flag that state if recovery was disabled * @max_notifyid: largest allocated notify id. + * @table_ptr: pointer to the resource table in effect + * @cached_table: copy of the resource table + * @table_csum: checksum of the resource table */ struct rproc { struct klist_node node; @@ -429,9 +432,13 @@ struct rproc { struct completion crash_comp; bool recovery_disabled; int max_notifyid; + struct resource_table *table_ptr; + struct resource_table *cached_table; + u32 table_csum; }; /* we currently support only two vrings per rvdev */ + #define RVDEV_NUM_VRINGS 2 /** @@ -462,16 +469,14 @@ struct rproc_vring { * @rproc: the rproc handle * @vdev: the virio device * @vring: the vrings for this vdev - * @dfeatures: virtio device features - * @gfeatures: virtio guest features + * @rsc_offset: offset of the vdev's resource entry */ struct rproc_vdev { struct list_head node; struct rproc *rproc; struct virtio_device vdev; struct rproc_vring vring[RVDEV_NUM_VRINGS]; - unsigned long dfeatures; - unsigned long gfeatures; + u32 rsc_offset; }; struct rproc *rproc_alloc(struct device *dev, const char *name, diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h index 5ae8456d9670..201a69749659 100644 --- a/include/linux/res_counter.h +++ b/include/linux/res_counter.h @@ -13,7 +13,8 @@ * info about what this counter is. */ -#include <linux/cgroup.h> +#include <linux/spinlock.h> +#include <linux/errno.h> /* * The core object. the cgroup that wishes to account for some @@ -53,7 +54,7 @@ struct res_counter { struct res_counter *parent; }; -#define RESOURCE_MAX (unsigned long long)LLONG_MAX +#define RES_COUNTER_MAX ULLONG_MAX /** * Helpers to interact with userspace diff --git a/include/linux/reservation.h b/include/linux/reservation.h new file mode 100644 index 000000000000..813dae960ebd --- /dev/null +++ b/include/linux/reservation.h @@ -0,0 +1,62 @@ +/* + * Header file for reservations for dma-buf and ttm + * + * Copyright(C) 2011 Linaro Limited. All rights reserved. + * Copyright (C) 2012-2013 Canonical Ltd + * Copyright (C) 2012 Texas Instruments + * + * Authors: + * Rob Clark <rob.clark@linaro.org> + * Maarten Lankhorst <maarten.lankhorst@canonical.com> + * Thomas Hellstrom <thellstrom-at-vmware-dot-com> + * + * Based on bo.c which bears the following copyright notice, + * but is dual licensed: + * + * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef _LINUX_RESERVATION_H +#define _LINUX_RESERVATION_H + +#include <linux/ww_mutex.h> + +extern struct ww_class reservation_ww_class; + +struct reservation_object { + struct ww_mutex lock; +}; + +static inline void +reservation_object_init(struct reservation_object *obj) +{ + ww_mutex_init(&obj->lock, &reservation_ww_class); +} + +static inline void +reservation_object_fini(struct reservation_object *obj) +{ + ww_mutex_destroy(&obj->lock); +} + +#endif /* _LINUX_RESERVATION_H */ diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h new file mode 100644 index 000000000000..2f61311ae3e0 --- /dev/null +++ b/include/linux/reset-controller.h @@ -0,0 +1,51 @@ +#ifndef _LINUX_RESET_CONTROLLER_H_ +#define _LINUX_RESET_CONTROLLER_H_ + +#include <linux/list.h> + +struct reset_controller_dev; + +/** + * struct reset_control_ops + * + * @reset: for self-deasserting resets, does all necessary + * things to reset the device + * @assert: manually assert the reset line, if supported + * @deassert: manually deassert the reset line, if supported + */ +struct reset_control_ops { + int (*reset)(struct reset_controller_dev *rcdev, unsigned long id); + int (*assert)(struct reset_controller_dev *rcdev, unsigned long id); + int (*deassert)(struct reset_controller_dev *rcdev, unsigned long id); +}; + +struct module; +struct device_node; + +/** + * struct reset_controller_dev - reset controller entity that might + * provide multiple reset controls + * @ops: a pointer to device specific struct reset_control_ops + * @owner: kernel module of the reset controller driver + * @list: internal list of reset controller devices + * @of_node: corresponding device tree node as phandle target + * @of_reset_n_cells: number of cells in reset line specifiers + * @of_xlate: translation function to translate from specifier as found in the + * device tree to id as given to the reset control ops + * @nr_resets: number of reset controls in this reset controller device + */ +struct reset_controller_dev { + struct reset_control_ops *ops; + struct module *owner; + struct list_head list; + struct device_node *of_node; + int of_reset_n_cells; + int (*of_xlate)(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec); + unsigned int nr_resets; +}; + +int reset_controller_register(struct reset_controller_dev *rcdev); +void reset_controller_unregister(struct reset_controller_dev *rcdev); + +#endif diff --git a/include/linux/reset.h b/include/linux/reset.h new file mode 100644 index 000000000000..6082247feab1 --- /dev/null +++ b/include/linux/reset.h @@ -0,0 +1,17 @@ +#ifndef _LINUX_RESET_H_ +#define _LINUX_RESET_H_ + +struct device; +struct reset_control; + +int reset_control_reset(struct reset_control *rstc); +int reset_control_assert(struct reset_control *rstc); +int reset_control_deassert(struct reset_control *rstc); + +struct reset_control *reset_control_get(struct device *dev, const char *id); +void reset_control_put(struct reset_control *rstc); +struct reset_control *devm_reset_control_get(struct device *dev, const char *id); + +int device_reset(struct device *dev); + +#endif diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 1342e69542f3..d69cf637a15a 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -4,6 +4,7 @@ #include <linux/kmemcheck.h> #include <linux/mm.h> #include <linux/seq_file.h> +#include <linux/poll.h> struct ring_buffer; struct ring_buffer_iter; @@ -96,6 +97,11 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k __ring_buffer_alloc((size), (flags), &__key); \ }) +void ring_buffer_wait(struct ring_buffer *buffer, int cpu); +int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu, + struct file *filp, poll_table *poll_table); + + #define RING_BUFFER_ALL_CPUS -1 void ring_buffer_free(struct ring_buffer *buffer); diff --git a/include/linux/rio.h b/include/linux/rio.h index a3e784278667..b71d5738e683 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -20,6 +20,7 @@ #include <linux/errno.h> #include <linux/device.h> #include <linux/rio_regs.h> +#include <linux/mod_devicetable.h> #ifdef CONFIG_RAPIDIO_DMA_ENGINE #include <linux/dmaengine.h> #endif @@ -83,7 +84,6 @@ extern struct bus_type rio_bus_type; extern struct device rio_bus; -extern struct list_head rio_devices; /* list of all devices */ struct rio_mport; struct rio_dev; @@ -92,9 +92,24 @@ union rio_pw_msg; /** * struct rio_switch - RIO switch info * @node: Node in global list of switches - * @switchid: Switch ID that is unique across a network * @route_table: Copy of switch routing table * @port_ok: Status of each port (one bit per port) - OK=1 or UNINIT=0 + * @ops: pointer to switch-specific operations + * @lock: lock to serialize operations updates + * @nextdev: Array of per-port pointers to the next attached device + */ +struct rio_switch { + struct list_head node; + u8 *route_table; + u32 port_ok; + struct rio_switch_ops *ops; + spinlock_t lock; + struct rio_dev *nextdev[0]; +}; + +/** + * struct rio_switch_ops - Per-switch operations + * @owner: The module owner of this structure * @add_entry: Callback for switch-specific route add function * @get_entry: Callback for switch-specific route get function * @clr_table: Callback for switch-specific clear route table function @@ -102,14 +117,12 @@ union rio_pw_msg; * @get_domain: Callback for switch-specific domain get function * @em_init: Callback for switch-specific error management init function * @em_handle: Callback for switch-specific error management handler function - * @sw_sysfs: Callback that initializes switch-specific sysfs attributes - * @nextdev: Array of per-port pointers to the next attached device + * + * Defines the operations that are necessary to initialize/control + * a particular RIO switch device. */ -struct rio_switch { - struct list_head node; - u16 switchid; - u8 *route_table; - u32 port_ok; +struct rio_switch_ops { + struct module *owner; int (*add_entry) (struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port); int (*get_entry) (struct rio_mport *mport, u16 destid, u8 hopcount, @@ -122,8 +135,6 @@ struct rio_switch { u8 *sw_domain); int (*em_init) (struct rio_dev *dev); int (*em_handle) (struct rio_dev *dev, u8 swport); - int (*sw_sysfs) (struct rio_dev *dev, int create); - struct rio_dev *nextdev[0]; }; /** @@ -131,6 +142,7 @@ struct rio_switch { * @global_list: Node in list of all RIO devices * @net_list: Node in list of RIO devices in a network * @net: Network this device is a part of + * @do_enum: Enumeration flag * @did: Device ID * @vid: Vendor ID * @device_rev: Device revision @@ -159,6 +171,7 @@ struct rio_dev { struct list_head global_list; /* node in list of all RIO devices */ struct list_head net_list; /* node in per net list */ struct rio_net *net; /* RIO net this device resides in */ + bool do_enum; u16 did; u16 vid; u32 device_rev; @@ -237,6 +250,7 @@ enum rio_phy_type { * @name: Port name string * @priv: Master port private data * @dma: DMA device associated with mport + * @nscan: RapidIO network enumeration/discovery operations */ struct rio_mport { struct list_head dbells; /* list of doorbell events */ @@ -262,8 +276,14 @@ struct rio_mport { #ifdef CONFIG_RAPIDIO_DMA_ENGINE struct dma_device dma; #endif + struct rio_scan *nscan; }; +/* + * Enumeration/discovery control flags + */ +#define RIO_SCAN_ENUM_NO_WAIT 0x00000001 /* Do not wait for enum completed */ + struct rio_id_table { u16 start; /* logical minimal id */ u32 max; /* max number of IDs in table */ @@ -291,10 +311,6 @@ struct rio_net { struct rio_id_table destid_table; /* destID allocation table */ }; -/* Definitions used by switch sysfs initialization callback */ -#define RIO_SW_SYSFS_CREATE 1 /* Create switch attributes */ -#define RIO_SW_SYSFS_REMOVE 0 /* Remove switch attributes */ - /* Low-level architecture-dependent routines */ /** @@ -379,35 +395,6 @@ struct rio_driver { #define to_rio_driver(drv) container_of(drv,struct rio_driver, driver) -/** - * struct rio_device_id - RIO device identifier - * @did: RIO device ID - * @vid: RIO vendor ID - * @asm_did: RIO assembly device ID - * @asm_vid: RIO assembly vendor ID - * - * Identifies a RIO device based on both the device/vendor IDs and - * the assembly device/vendor IDs. - */ -struct rio_device_id { - u16 did, vid; - u16 asm_did, asm_vid; -}; - -/** - * struct rio_switch_ops - Per-switch operations - * @vid: RIO vendor ID - * @did: RIO device ID - * @init_hook: Callback that performs switch device initialization - * - * Defines the operations that are necessary to initialize/control - * a particular RIO switch device. - */ -struct rio_switch_ops { - u16 vid, did; - int (*init_hook) (struct rio_dev *rdev, int do_enum); -}; - union rio_pw_msg { struct { u32 comptag; /* Component Tag CSR */ @@ -460,6 +447,31 @@ static inline struct rio_mport *dma_to_mport(struct dma_device *ddev) } #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ +/** + * struct rio_scan - RIO enumeration and discovery operations + * @owner: The module owner of this structure + * @enumerate: Callback to perform RapidIO fabric enumeration. + * @discover: Callback to perform RapidIO fabric discovery. + */ +struct rio_scan { + struct module *owner; + int (*enumerate)(struct rio_mport *mport, u32 flags); + int (*discover)(struct rio_mport *mport, u32 flags); +}; + +/** + * struct rio_scan_node - list node to register RapidIO enumeration and + * discovery methods with RapidIO core. + * @mport_id: ID of an mport (net) serviced by this enumerator + * @node: node in global list of registered enumerators + * @ops: RIO enumeration and discovery operations + */ +struct rio_scan_node { + int mport_id; + struct list_head node; + struct rio_scan *ops; +}; + /* Architecture and hardware-specific functions */ extern int rio_register_mport(struct rio_mport *); extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int); diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h index b75c05920ab5..5059994fe297 100644 --- a/include/linux/rio_drv.h +++ b/include/linux/rio_drv.h @@ -433,5 +433,6 @@ extern u16 rio_local_get_device_id(struct rio_mport *port); extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from); extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did, struct rio_dev *from); +extern int rio_init_mports(void); #endif /* LINUX_RIO_DRV_H */ diff --git a/include/linux/rio_ids.h b/include/linux/rio_ids.h index b66d13d1bdc0..2543bc163d54 100644 --- a/include/linux/rio_ids.h +++ b/include/linux/rio_ids.h @@ -13,8 +13,6 @@ #ifndef LINUX_RIO_IDS_H #define LINUX_RIO_IDS_H -#define RIO_ANY_ID 0xffff - #define RIO_VID_FREESCALE 0x0002 #define RIO_DID_MPC8560 0x0003 diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 580b24c8b8ca..c2c28975293c 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -133,7 +133,13 @@ extern struct rtc_device *rtc_device_register(const char *name, struct device *dev, const struct rtc_class_ops *ops, struct module *owner); +extern struct rtc_device *devm_rtc_device_register(struct device *dev, + const char *name, + const struct rtc_class_ops *ops, + struct module *owner); extern void rtc_device_unregister(struct rtc_device *rtc); +extern void devm_rtc_device_unregister(struct device *dev, + struct rtc_device *rtc); extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm); extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm); diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 489dd7bb28ec..f28544b2f9af 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -69,6 +69,15 @@ extern int ndo_dflt_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, struct net_device *dev, int idx); +extern int ndo_dflt_fdb_add(struct ndmsg *ndm, + struct nlattr *tb[], + struct net_device *dev, + const unsigned char *addr, + u16 flags); +extern int ndo_dflt_fdb_del(struct ndmsg *ndm, + struct nlattr *tb[], + struct net_device *dev, + const unsigned char *addr); extern int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, struct net_device *dev, u16 mode); diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index 8da67d625e13..0616ffe45702 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h @@ -133,10 +133,20 @@ do { \ _down_write_nest_lock(sem, &(nest_lock)->dep_map); \ } while (0); +/* + * Take/release a lock when not the owner will release it. + * + * [ This API should be avoided as much as possible - the + * proper abstraction for this case is completions. ] + */ +extern void down_read_non_owner(struct rw_semaphore *sem); +extern void up_read_non_owner(struct rw_semaphore *sem); #else # define down_read_nested(sem, subclass) down_read(sem) # define down_write_nest_lock(sem, nest_lock) down_write(sem) # define down_write_nested(sem, subclass) down_write(sem) +# define down_read_non_owner(sem) down_read(sem) +# define up_read_non_owner(sem) up_read(sem) #endif #endif /* _LINUX_RWSEM_H */ diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 2d8bdaef9611..adae88f5b0ab 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -111,6 +111,9 @@ static inline struct page *sg_page(struct scatterlist *sg) static inline void sg_set_buf(struct scatterlist *sg, const void *buf, unsigned int buflen) { +#ifdef CONFIG_DEBUG_SG + BUG_ON(!virt_addr_valid(buf)); +#endif sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); } @@ -172,6 +175,22 @@ static inline void sg_mark_end(struct scatterlist *sg) } /** + * sg_unmark_end - Undo setting the end of the scatterlist + * @sg: SG entryScatterlist + * + * Description: + * Removes the termination marker from the given entry of the scatterlist. + * + **/ +static inline void sg_unmark_end(struct scatterlist *sg) +{ +#ifdef CONFIG_DEBUG_SG + BUG_ON(sg->sg_magic != SG_MAGIC); +#endif + sg->page_link &= ~0x02; +} + +/** * sg_phys - Return physical address of an sg entry * @sg: SG entry * @@ -225,6 +244,11 @@ size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents, size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, size_t buflen); +size_t sg_pcopy_from_buffer(struct scatterlist *sgl, unsigned int nents, + void *buf, size_t buflen, off_t skip); +size_t sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents, + void *buf, size_t buflen, off_t skip); + /* * Maximum number of entries that will be allocated in one piece, if * a list larger than this is required then chaining will be utilized. @@ -235,13 +259,13 @@ size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents, * sg page iterator * * Iterates over sg entries page-by-page. On each successful iteration, - * @piter->page points to the current page, @piter->sg to the sg holding this - * page and @piter->sg_pgoffset to the page's page offset within the sg. The - * iteration will stop either when a maximum number of sg entries was reached - * or a terminating sg (sg_last(sg) == true) was reached. + * you can call sg_page_iter_page(@piter) and sg_page_iter_dma_address(@piter) + * to get the current page and its dma address. @piter->sg will point to the + * sg holding this page and @piter->sg_pgoffset to the page's page offset + * within the sg. The iteration will stop either when a maximum number of sg + * entries was reached or a terminating sg (sg_last(sg) == true) was reached. */ struct sg_page_iter { - struct page *page; /* current page */ struct scatterlist *sg; /* sg holding the page */ unsigned int sg_pgoffset; /* page offset within the sg */ @@ -255,6 +279,24 @@ bool __sg_page_iter_next(struct sg_page_iter *piter); void __sg_page_iter_start(struct sg_page_iter *piter, struct scatterlist *sglist, unsigned int nents, unsigned long pgoffset); +/** + * sg_page_iter_page - get the current page held by the page iterator + * @piter: page iterator holding the page + */ +static inline struct page *sg_page_iter_page(struct sg_page_iter *piter) +{ + return nth_page(sg_page(piter->sg), piter->sg_pgoffset); +} + +/** + * sg_page_iter_dma_address - get the dma address of the current page held by + * the page iterator. + * @piter: page iterator holding the page + */ +static inline dma_addr_t sg_page_iter_dma_address(struct sg_page_iter *piter) +{ + return sg_dma_address(piter->sg) + (piter->sg_pgoffset << PAGE_SHIFT); +} /** * for_each_sg_page - iterate over the pages of the given sg list diff --git a/include/linux/sched.h b/include/linux/sched.h index d35d2b6ddbfb..b09798b672f3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -22,6 +22,7 @@ struct sched_param { #include <linux/errno.h> #include <linux/nodemask.h> #include <linux/mm_types.h> +#include <linux/preempt.h> #include <asm/page.h> #include <asm/ptrace.h> @@ -107,14 +108,6 @@ extern unsigned long this_cpu_load(void); extern void calc_global_load(unsigned long ticks); extern void update_cpu_load_nohz(void); -/* Notifier for when a task gets migrated to a new CPU */ -struct task_migration_notifier { - struct task_struct *task; - int from_cpu; - int to_cpu; -}; -extern void register_task_migration_notifier(struct notifier_block *n); - extern unsigned long get_parent_ip(unsigned long addr); extern void dump_cpu_task(int cpu); @@ -127,18 +120,6 @@ extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m); extern void proc_sched_set_task(struct task_struct *p); extern void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq); -#else -static inline void -proc_sched_show_task(struct task_struct *p, struct seq_file *m) -{ -} -static inline void proc_sched_set_task(struct task_struct *p) -{ -} -static inline void -print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) -{ -} #endif /* @@ -163,9 +144,10 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) #define TASK_DEAD 64 #define TASK_WAKEKILL 128 #define TASK_WAKING 256 -#define TASK_STATE_MAX 512 +#define TASK_PARKED 512 +#define TASK_STATE_MAX 1024 -#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKW" +#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKWP" extern char ___assert_task_state[1 - 2*!!( sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1)]; @@ -242,7 +224,7 @@ extern void init_idle_bootup_task(struct task_struct *idle); extern int runqueue_is_locked(int cpu); -#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) +#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON) extern void nohz_balance_enter_idle(int cpu); extern void set_cpu_sd_state_idle(void); extern int get_nohz_timer_target(void); @@ -320,13 +302,10 @@ extern signed long schedule_timeout_killable(signed long timeout); extern signed long schedule_timeout_uninterruptible(signed long timeout); asmlinkage void schedule(void); extern void schedule_preempt_disabled(void); -extern int mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner); struct nsproxy; struct user_namespace; -#include <linux/aio.h> - #ifdef CONFIG_MMU extern void arch_pick_mmap_layout(struct mm_struct *mm); extern unsigned long @@ -336,8 +315,6 @@ extern unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); -extern void arch_unmap_area(struct mm_struct *, unsigned long); -extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long); #else static inline void arch_pick_mmap_layout(struct mm_struct *mm) {} #endif @@ -451,6 +428,14 @@ struct task_cputime { .sum_exec_runtime = 0, \ } +#define PREEMPT_ENABLED (PREEMPT_NEED_RESCHED) + +#ifdef CONFIG_PREEMPT_COUNT +#define PREEMPT_DISABLED (1 + PREEMPT_ENABLED) +#else +#define PREEMPT_DISABLED PREEMPT_ENABLED +#endif + /* * Disable preemption until the scheduler is running. * Reset by start_kernel()->sched_init()->init_idle(). @@ -458,7 +443,7 @@ struct task_cputime { * We include PREEMPT_ACTIVE to avoid cond_resched() from working * before the scheduler is active -- see should_resched(). */ -#define INIT_PREEMPT_COUNT (1 + PREEMPT_ACTIVE) +#define INIT_PREEMPT_COUNT (PREEMPT_DISABLED + PREEMPT_ACTIVE) /** * struct thread_group_cputimer - thread group interval timer counts @@ -526,7 +511,8 @@ struct signal_struct { unsigned int has_child_subreaper:1; /* POSIX.1b Interval Timers */ - struct list_head posix_timers; + int posix_timer_id; + struct list_head posix_timers; /* ITIMER_REAL timer for the process */ struct hrtimer real_timer; @@ -570,7 +556,7 @@ struct signal_struct { cputime_t utime, stime, cutime, cstime; cputime_t gtime; cputime_t cgtime; -#ifndef CONFIG_VIRT_CPU_ACCOUNTING +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE struct cputime prev_cputime; #endif unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; @@ -606,6 +592,7 @@ struct signal_struct { #endif #ifdef CONFIG_AUDIT unsigned audit_tty; + unsigned audit_tty_log_passwd; struct tty_audit_buf *tty_audit_buf; #endif #ifdef CONFIG_CGROUPS @@ -637,6 +624,7 @@ struct signal_struct { #define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */ #define SIGNAL_STOP_CONTINUED 0x00000002 /* SIGCONT since WCONTINUED reap */ #define SIGNAL_GROUP_EXIT 0x00000004 /* group exit in progress */ +#define SIGNAL_GROUP_COREDUMP 0x00000008 /* coredump in progress */ /* * Pending notifications to parent. */ @@ -768,31 +756,6 @@ enum cpu_idle_type { }; /* - * Increase resolution of nice-level calculations for 64-bit architectures. - * The extra resolution improves shares distribution and load balancing of - * low-weight task groups (eg. nice +19 on an autogroup), deeper taskgroup - * hierarchies, especially on larger systems. This is not a user-visible change - * and does not change the user-interface for setting shares/weights. - * - * We increase resolution only if we have enough bits to allow this increased - * resolution (i.e. BITS_PER_LONG > 32). The costs for increasing resolution - * when BITS_PER_LONG <= 32 are pretty high and the returns do not justify the - * increased costs. - */ -#if 0 /* BITS_PER_LONG > 32 -- currently broken: it increases power usage under light load */ -# define SCHED_LOAD_RESOLUTION 10 -# define scale_load(w) ((w) << SCHED_LOAD_RESOLUTION) -# define scale_load_down(w) ((w) >> SCHED_LOAD_RESOLUTION) -#else -# define SCHED_LOAD_RESOLUTION 0 -# define scale_load(w) (w) -# define scale_load_down(w) (w) -#endif - -#define SCHED_LOAD_SHIFT (10 + SCHED_LOAD_RESOLUTION) -#define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT) - -/* * Increase resolution of cpu_power calculations */ #define SCHED_POWER_SHIFT 10 @@ -817,62 +780,6 @@ enum cpu_idle_type { extern int __weak arch_sd_sibiling_asym_packing(void); -struct sched_group_power { - atomic_t ref; - /* - * CPU power of this group, SCHED_LOAD_SCALE being max power for a - * single CPU. - */ - unsigned int power, power_orig; - unsigned long next_update; - /* - * Number of busy cpus in this group. - */ - atomic_t nr_busy_cpus; - - unsigned long cpumask[0]; /* iteration mask */ -}; - -struct sched_group { - struct sched_group *next; /* Must be a circular list */ - atomic_t ref; - - unsigned int group_weight; - struct sched_group_power *sgp; - - /* - * The CPUs this group covers. - * - * NOTE: this field is variable length. (Allocated dynamically - * by attaching extra space to the end of the structure, - * depending on how many CPUs the kernel has booted up with) - */ - unsigned long cpumask[0]; -}; - -static inline struct cpumask *sched_group_cpus(struct sched_group *sg) -{ - return to_cpumask(sg->cpumask); -} - -/* - * cpumask masking which cpus in the group are allowed to iterate up the domain - * tree. - */ -static inline struct cpumask *sched_group_mask(struct sched_group *sg) -{ - return to_cpumask(sg->sgp->cpumask); -} - -/** - * group_first_cpu - Returns the first cpu in the cpumask of a sched_group. - * @group: The group whose first cpu is to be returned. - */ -static inline unsigned int group_first_cpu(struct sched_group *group) -{ - return cpumask_first(sched_group_cpus(group)); -} - struct sched_domain_attr { int relax_domain_level; }; @@ -883,6 +790,8 @@ struct sched_domain_attr { extern int sched_domain_level_max; +struct sched_group; + struct sched_domain { /* These fields must be setup */ struct sched_domain *parent; /* top domain must be null terminated */ @@ -899,6 +808,8 @@ struct sched_domain { unsigned int wake_idx; unsigned int forkexec_idx; unsigned int smt_gain; + + int nohz_idle; /* NOHZ IDLE status */ int flags; /* See SD_* */ int level; @@ -909,6 +820,10 @@ struct sched_domain { u64 last_update; + /* idle_balance() stats */ + u64 max_newidle_lb_cost; + unsigned long next_decay_max_lb_cost; + #ifdef CONFIG_SCHEDSTATS /* load_balance() stats */ unsigned int lb_count[CPU_MAX_IDLE_TYPES]; @@ -971,18 +886,6 @@ extern void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[], cpumask_var_t *alloc_sched_domains(unsigned int ndoms); void free_sched_domains(cpumask_var_t doms[], unsigned int ndoms); -/* Test a flag in parent sched domain */ -static inline int test_sd_parent(struct sched_domain *sd, int flag) -{ - if (sd->parent && (sd->parent->flags & flag)) - return 1; - - return 0; -} - -unsigned long default_scale_freq_power(struct sched_domain *sd, int cpu); -unsigned long default_scale_smt_power(struct sched_domain *sd, int cpu); - bool cpus_share_cache(int this_cpu, int that_cpu); #else /* CONFIG_SMP */ @@ -1017,72 +920,6 @@ struct mempolicy; struct pipe_inode_info; struct uts_namespace; -struct rq; -struct sched_domain; - -/* - * wake flags - */ -#define WF_SYNC 0x01 /* waker goes to sleep after wakup */ -#define WF_FORK 0x02 /* child wakeup after fork */ -#define WF_MIGRATED 0x04 /* internal use, task got migrated */ - -#define ENQUEUE_WAKEUP 1 -#define ENQUEUE_HEAD 2 -#ifdef CONFIG_SMP -#define ENQUEUE_WAKING 4 /* sched_class::task_waking was called */ -#else -#define ENQUEUE_WAKING 0 -#endif - -#define DEQUEUE_SLEEP 1 - -struct sched_class { - const struct sched_class *next; - - void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags); - void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags); - void (*yield_task) (struct rq *rq); - bool (*yield_to_task) (struct rq *rq, struct task_struct *p, bool preempt); - - void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int flags); - - struct task_struct * (*pick_next_task) (struct rq *rq); - void (*put_prev_task) (struct rq *rq, struct task_struct *p); - -#ifdef CONFIG_SMP - int (*select_task_rq)(struct task_struct *p, int sd_flag, int flags); - void (*migrate_task_rq)(struct task_struct *p, int next_cpu); - - void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); - void (*post_schedule) (struct rq *this_rq); - void (*task_waking) (struct task_struct *task); - void (*task_woken) (struct rq *this_rq, struct task_struct *task); - - void (*set_cpus_allowed)(struct task_struct *p, - const struct cpumask *newmask); - - void (*rq_online)(struct rq *rq); - void (*rq_offline)(struct rq *rq); -#endif - - void (*set_curr_task) (struct rq *rq); - void (*task_tick) (struct rq *rq, struct task_struct *p, int queued); - void (*task_fork) (struct task_struct *p); - - void (*switched_from) (struct rq *this_rq, struct task_struct *task); - void (*switched_to) (struct rq *this_rq, struct task_struct *task); - void (*prio_changed) (struct rq *this_rq, struct task_struct *task, - int oldprio); - - unsigned int (*get_rr_interval) (struct rq *rq, - struct task_struct *task); - -#ifdef CONFIG_FAIR_GROUP_SCHED - void (*task_move_group) (struct task_struct *p, int on_rq); -#endif -}; - struct load_weight { unsigned long weight, inv_weight; }; @@ -1090,7 +927,7 @@ struct load_weight { struct sched_avg { /* * These sums represent an infinite geometric series and so are bound - * above by 1024/(1-y). Thus we only need a u32 to store them for for all + * above by 1024/(1-y). Thus we only need a u32 to store them for all * choices of y < 1-2^(-32)*1024. */ u32 runnable_avg_sum, runnable_avg_period; @@ -1160,12 +997,7 @@ struct sched_entity { struct cfs_rq *my_q; #endif -/* - * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be - * removed when useful for applications beyond shares distribution (e.g. - * load-balance). - */ -#if defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED) +#ifdef CONFIG_SMP /* Per-entity load-tracking */ struct sched_avg avg; #endif @@ -1207,6 +1039,9 @@ struct task_struct { #ifdef CONFIG_SMP struct llist_node wake_entry; int on_cpu; + struct task_struct *last_wakee; + unsigned long wakee_flips; + unsigned long wakee_flip_decay_ts; #endif int on_rq; @@ -1274,8 +1109,10 @@ struct task_struct { int exit_code, exit_signal; int pdeath_signal; /* The signal sent when the parent dies */ unsigned int jobctl; /* JOBCTL_*, siglock protected */ - /* ??? */ + + /* Used for emulating ABI behavior of previous Linux versions */ unsigned int personality; + unsigned did_exec:1; unsigned in_execve:1; /* Tell the LSMs that the process is doing an * execve */ @@ -1327,7 +1164,7 @@ struct task_struct { cputime_t utime, stime, utimescaled, stimescaled; cputime_t gtime; -#ifndef CONFIG_VIRT_CPU_ACCOUNTING +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE struct cputime prev_cputime; #endif #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN @@ -1569,13 +1406,21 @@ struct task_struct { unsigned long memsw_nr_pages; /* uncharged mem+swap usage */ } memcg_batch; unsigned int memcg_kmem_skip_account; -#endif -#ifdef CONFIG_HAVE_HW_BREAKPOINT - atomic_t ptrace_bp_refcnt; + struct memcg_oom_info { + unsigned int may_oom:1; + unsigned int in_memcg_oom:1; + unsigned int oom_locked:1; + int wakeups; + struct mem_cgroup *wait_on_memcg; + } memcg_oom; #endif #ifdef CONFIG_UPROBES struct uprobe_task *utask; #endif +#if defined(CONFIG_BCACHE) || defined(CONFIG_BCACHE_MODULE) + unsigned int sequential_io; + unsigned int sequential_io_avg; +#endif }; /* Future-safe accessor for struct task_struct's cpus_allowed. */ @@ -1702,6 +1547,8 @@ static inline pid_t task_pgrp_nr(struct task_struct *tsk) * Test if a process is not yet dead (at most zombie state) * If pid_alive fails, then pointers within the task structure * can be stale and must not be dereferenced. + * + * Return: 1 if the process is alive. 0 otherwise. */ static inline int pid_alive(struct task_struct *p) { @@ -1713,6 +1560,8 @@ static inline int pid_alive(struct task_struct *p) * @tsk: Task structure to be checked. * * Check if a task structure is the first user space task the kernel created. + * + * Return: 1 if the task structure is init. 0 otherwise. */ static inline int is_global_init(struct task_struct *tsk) { @@ -1793,11 +1642,12 @@ extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, #define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ #define PF_SPREAD_PAGE 0x01000000 /* Spread page cache over cpuset */ #define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */ -#define PF_THREAD_BOUND 0x04000000 /* Thread bound to specific cpu */ +#define PF_NO_SETAFFINITY 0x04000000 /* Userland is not allowed to meddle with cpus_allowed */ #define PF_MCE_EARLY 0x08000000 /* Early kill for mce process policy */ #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */ +#define PF_SUSPEND_TASK 0x80000000 /* this thread called freeze_processes and should not be frozen */ /* * Only the _current_ task can read/write to tsk->flags, but other @@ -1927,13 +1777,13 @@ static inline int set_cpus_allowed_ptr(struct task_struct *p, } #endif -#ifdef CONFIG_NO_HZ +#ifdef CONFIG_NO_HZ_COMMON void calc_load_enter_idle(void); void calc_load_exit_idle(void); #else static inline void calc_load_enter_idle(void) { } static inline void calc_load_exit_idle(void) { } -#endif /* CONFIG_NO_HZ */ +#endif /* CONFIG_NO_HZ_COMMON */ #ifndef CONFIG_CPUMASK_OFFSTACK static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) @@ -2019,10 +1869,17 @@ extern void idle_task_exit(void); static inline void idle_task_exit(void) {} #endif -#if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP) -extern void wake_up_idle_cpu(int cpu); +#if defined(CONFIG_NO_HZ_COMMON) && defined(CONFIG_SMP) +extern void wake_up_nohz_cpu(int cpu); #else -static inline void wake_up_idle_cpu(int cpu) { } +static inline void wake_up_nohz_cpu(int cpu) { } +#endif + +#ifdef CONFIG_NO_HZ_FULL +extern bool sched_can_stop_tick(void); +extern u64 scheduler_tick_max_deferment(void); +#else +static inline bool sched_can_stop_tick(void) { return false; } #endif #ifdef CONFIG_SCHED_AUTOGROUP @@ -2056,6 +1913,8 @@ extern struct task_struct *idle_task(int cpu); /** * is_idle_task - is the specified task an idle task? * @p: the task in question. + * + * Return: 1 if @p is an idle task. 0 otherwise. */ static inline bool is_idle_task(const struct task_struct *p) { @@ -2108,8 +1967,6 @@ extern struct task_struct *find_task_by_vpid(pid_t nr); extern struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns); -extern void __set_special_pids(struct pid *pid); - /* per-UID process charging. */ extern struct user_struct * alloc_uid(kuid_t); static inline struct user_struct *get_uid(struct user_struct *u) @@ -2332,15 +2189,15 @@ static inline bool thread_group_leader(struct task_struct *p) * all we care about is that we have a task with the appropriate * pid, we don't actually care if we have the right task. */ -static inline int has_group_leader_pid(struct task_struct *p) +static inline bool has_group_leader_pid(struct task_struct *p) { - return p->pid == p->tgid; + return task_pid(p) == p->signal->leader_pid; } static inline -int same_thread_group(struct task_struct *p1, struct task_struct *p2) +bool same_thread_group(struct task_struct *p1, struct task_struct *p2) { - return p1->tgid == p2->tgid; + return p1->signal == p2->signal; } static inline struct task_struct *next_thread(const struct task_struct *p) @@ -2412,27 +2269,18 @@ static inline void threadgroup_change_end(struct task_struct *tsk) * * Lock the threadgroup @tsk belongs to. No new task is allowed to enter * and member tasks aren't allowed to exit (as indicated by PF_EXITING) or - * perform exec. This is useful for cases where the threadgroup needs to - * stay stable across blockable operations. + * change ->group_leader/pid. This is useful for cases where the threadgroup + * needs to stay stable across blockable operations. * * fork and exit paths explicitly call threadgroup_change_{begin|end}() for * synchronization. While held, no new task will be added to threadgroup * and no existing live task will have its PF_EXITING set. * - * During exec, a task goes and puts its thread group through unusual - * changes. After de-threading, exclusive access is assumed to resources - * which are usually shared by tasks in the same group - e.g. sighand may - * be replaced with a new one. Also, the exec'ing task takes over group - * leader role including its pid. Exclude these changes while locked by - * grabbing cred_guard_mutex which is used to synchronize exec path. + * de_thread() does threadgroup_change_{begin|end}() when a non-leader + * sub-thread becomes a new leader. */ static inline void threadgroup_lock(struct task_struct *tsk) { - /* - * exec uses exit for de-threading nesting group_rwsem inside - * cred_guard_mutex. Grab cred_guard_mutex first. - */ - mutex_lock(&tsk->signal->cred_guard_mutex); down_write(&tsk->signal->group_rwsem); } @@ -2445,7 +2293,6 @@ static inline void threadgroup_lock(struct task_struct *tsk) static inline void threadgroup_unlock(struct task_struct *tsk) { up_write(&tsk->signal->group_rwsem); - mutex_unlock(&tsk->signal->cred_guard_mutex); } #else static inline void threadgroup_change_begin(struct task_struct *tsk) {} @@ -2568,11 +2415,6 @@ static inline int signal_pending_state(long state, struct task_struct *p) return (state & TASK_INTERRUPTIBLE) || __fatal_signal_pending(p); } -static inline int need_resched(void) -{ - return unlikely(test_thread_flag(TIF_NEED_RESCHED)); -} - /* * cond_resched() and cond_resched_lock(): latency reduction via * explicit rescheduling in places that are safe. The return @@ -2607,6 +2449,15 @@ extern int __cond_resched_softirq(void); __cond_resched_softirq(); \ }) +static inline void cond_resched_rcu(void) +{ +#if defined(CONFIG_DEBUG_ATOMIC_SLEEP) || !defined(CONFIG_PREEMPT_RCU) + rcu_read_unlock(); + cond_resched(); + rcu_read_lock(); +#endif +} + /* * Does a critical section need to be broken due to another * task waiting?: (technically does not depend on CONFIG_PREEMPT, @@ -2622,6 +2473,111 @@ static inline int spin_needbreak(spinlock_t *lock) } /* + * Idle thread specific functions to determine the need_resched + * polling state. We have two versions, one based on TS_POLLING in + * thread_info.status and one based on TIF_POLLING_NRFLAG in + * thread_info.flags + */ +#ifdef TS_POLLING +static inline int tsk_is_polling(struct task_struct *p) +{ + return task_thread_info(p)->status & TS_POLLING; +} +static inline void __current_set_polling(void) +{ + current_thread_info()->status |= TS_POLLING; +} + +static inline bool __must_check current_set_polling_and_test(void) +{ + __current_set_polling(); + + /* + * Polling state must be visible before we test NEED_RESCHED, + * paired by resched_task() + */ + smp_mb(); + + return unlikely(tif_need_resched()); +} + +static inline void __current_clr_polling(void) +{ + current_thread_info()->status &= ~TS_POLLING; +} + +static inline bool __must_check current_clr_polling_and_test(void) +{ + __current_clr_polling(); + + /* + * Polling state must be visible before we test NEED_RESCHED, + * paired by resched_task() + */ + smp_mb(); + + return unlikely(tif_need_resched()); +} +#elif defined(TIF_POLLING_NRFLAG) +static inline int tsk_is_polling(struct task_struct *p) +{ + return test_tsk_thread_flag(p, TIF_POLLING_NRFLAG); +} + +static inline void __current_set_polling(void) +{ + set_thread_flag(TIF_POLLING_NRFLAG); +} + +static inline bool __must_check current_set_polling_and_test(void) +{ + __current_set_polling(); + + /* + * Polling state must be visible before we test NEED_RESCHED, + * paired by resched_task() + * + * XXX: assumes set/clear bit are identical barrier wise. + */ + smp_mb__after_clear_bit(); + + return unlikely(tif_need_resched()); +} + +static inline void __current_clr_polling(void) +{ + clear_thread_flag(TIF_POLLING_NRFLAG); +} + +static inline bool __must_check current_clr_polling_and_test(void) +{ + __current_clr_polling(); + + /* + * Polling state must be visible before we test NEED_RESCHED, + * paired by resched_task() + */ + smp_mb__after_clear_bit(); + + return unlikely(tif_need_resched()); +} + +#else +static inline int tsk_is_polling(struct task_struct *p) { return 0; } +static inline void __current_set_polling(void) { } +static inline void __current_clr_polling(void) { } + +static inline bool __must_check current_set_polling_and_test(void) +{ + return unlikely(tif_need_resched()); +} +static inline bool __must_check current_clr_polling_and_test(void) +{ + return unlikely(tif_need_resched()); +} +#endif + +/* * Thread group CPU time accounting. */ void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times); @@ -2681,28 +2637,7 @@ extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask); extern long sched_getaffinity(pid_t pid, struct cpumask *mask); #ifdef CONFIG_CGROUP_SCHED - extern struct task_group root_task_group; - -extern struct task_group *sched_create_group(struct task_group *parent); -extern void sched_online_group(struct task_group *tg, - struct task_group *parent); -extern void sched_destroy_group(struct task_group *tg); -extern void sched_offline_group(struct task_group *tg); -extern void sched_move_task(struct task_struct *tsk); -#ifdef CONFIG_FAIR_GROUP_SCHED -extern int sched_group_set_shares(struct task_group *tg, unsigned long shares); -extern unsigned long sched_group_shares(struct task_group *tg); -#endif -#ifdef CONFIG_RT_GROUP_SCHED -extern int sched_group_set_rt_runtime(struct task_group *tg, - long rt_runtime_us); -extern long sched_group_rt_runtime(struct task_group *tg); -extern int sched_group_set_rt_period(struct task_group *tg, - long rt_period_us); -extern long sched_group_rt_period(struct task_group *tg); -extern int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk); -#endif #endif /* CONFIG_CGROUP_SCHED */ extern int task_can_switch_user(struct user_struct *up, diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index bf8086b2506e..9552afa733d8 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -2,8 +2,8 @@ #define _SCHED_SYSCTL_H #ifdef CONFIG_DETECT_HUNG_TASK +extern int sysctl_hung_task_check_count; extern unsigned int sysctl_hung_task_panic; -extern unsigned long sysctl_hung_task_check_count; extern unsigned long sysctl_hung_task_timeout_secs; extern unsigned long sysctl_hung_task_warnings; extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, diff --git a/include/linux/sched_clock.h b/include/linux/sched_clock.h new file mode 100644 index 000000000000..eca7abeb86fc --- /dev/null +++ b/include/linux/sched_clock.h @@ -0,0 +1,23 @@ +/* + * sched_clock.h: support for extending counters to full 64-bit ns counter + * + * 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_SCHED_CLOCK +#define LINUX_SCHED_CLOCK + +#ifdef CONFIG_GENERIC_SCHED_CLOCK +extern void sched_clock_postinit(void); +#else +static inline void sched_clock_postinit(void) { } +#endif + +extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); +extern void sched_clock_register(u64 (*read)(void), int bits, + unsigned long rate); + +extern unsigned long long (*sched_clock_func)(void); + +#endif diff --git a/include/linux/sctp.h b/include/linux/sctp.h index c11a28706fa4..3bfe8d6ee248 100644 --- a/include/linux/sctp.h +++ b/include/linux/sctp.h @@ -53,7 +53,9 @@ #include <linux/in.h> /* We need in_addr. */ #include <linux/in6.h> /* We need in6_addr. */ +#include <linux/skbuff.h> +#include <uapi/linux/sctp.h> /* Section 3.1. SCTP Common Header Format */ typedef struct sctphdr { @@ -63,14 +65,10 @@ typedef struct sctphdr { __le32 checksum; } __packed sctp_sctphdr_t; -#ifdef __KERNEL__ -#include <linux/skbuff.h> - static inline struct sctphdr *sctp_hdr(const struct sk_buff *skb) { return (struct sctphdr *)skb_transport_header(skb); } -#endif /* Section 3.2. Chunk Field Descriptions. */ typedef struct sctp_chunkhdr { diff --git a/include/linux/sdb.h b/include/linux/sdb.h new file mode 100644 index 000000000000..fbb76a46c8a5 --- /dev/null +++ b/include/linux/sdb.h @@ -0,0 +1,159 @@ +/* + * This is the official version 1.1 of sdb.h + */ +#ifndef __SDB_H__ +#define __SDB_H__ +#ifdef __KERNEL__ +#include <linux/types.h> +#else +#include <stdint.h> +#endif + +/* + * All structures are 64 bytes long and are expected + * to live in an array, one for each interconnect. + * Most fields of the structures are shared among the + * various types, and most-specific fields are at the + * beginning (for alignment reasons, and to keep the + * magic number at the head of the interconnect record + */ + +/* Product, 40 bytes at offset 24, 8-byte aligned + * + * device_id is vendor-assigned; version is device-specific, + * date is hex (e.g 0x20120501), name is UTF-8, blank-filled + * and not terminated with a 0 byte. + */ +struct sdb_product { + uint64_t vendor_id; /* 0x18..0x1f */ + uint32_t device_id; /* 0x20..0x23 */ + uint32_t version; /* 0x24..0x27 */ + uint32_t date; /* 0x28..0x2b */ + uint8_t name[19]; /* 0x2c..0x3e */ + uint8_t record_type; /* 0x3f */ +}; + +/* + * Component, 56 bytes at offset 8, 8-byte aligned + * + * The address range is first to last, inclusive + * (for example 0x100000 - 0x10ffff) + */ +struct sdb_component { + uint64_t addr_first; /* 0x08..0x0f */ + uint64_t addr_last; /* 0x10..0x17 */ + struct sdb_product product; /* 0x18..0x3f */ +}; + +/* Type of the SDB record */ +enum sdb_record_type { + sdb_type_interconnect = 0x00, + sdb_type_device = 0x01, + sdb_type_bridge = 0x02, + sdb_type_integration = 0x80, + sdb_type_repo_url = 0x81, + sdb_type_synthesis = 0x82, + sdb_type_empty = 0xFF, +}; + +/* Type 0: interconnect (first of the array) + * + * sdb_records is the length of the table including this first + * record, version is 1. The bus type is enumerated later. + */ +#define SDB_MAGIC 0x5344422d /* "SDB-" */ +struct sdb_interconnect { + uint32_t sdb_magic; /* 0x00-0x03 */ + uint16_t sdb_records; /* 0x04-0x05 */ + uint8_t sdb_version; /* 0x06 */ + uint8_t sdb_bus_type; /* 0x07 */ + struct sdb_component sdb_component; /* 0x08-0x3f */ +}; + +/* Type 1: device + * + * class is 0 for "custom device", other values are + * to be standardized; ABI version is for the driver, + * bus-specific bits are defined by each bus (see below) + */ +struct sdb_device { + uint16_t abi_class; /* 0x00-0x01 */ + uint8_t abi_ver_major; /* 0x02 */ + uint8_t abi_ver_minor; /* 0x03 */ + uint32_t bus_specific; /* 0x04-0x07 */ + struct sdb_component sdb_component; /* 0x08-0x3f */ +}; + +/* Type 2: bridge + * + * child is the address of the nested SDB table + */ +struct sdb_bridge { + uint64_t sdb_child; /* 0x00-0x07 */ + struct sdb_component sdb_component; /* 0x08-0x3f */ +}; + +/* Type 0x80: integration + * + * all types with bit 7 set are meta-information, so + * software can ignore the types it doesn't know. Here we + * just provide product information for an aggregate device + */ +struct sdb_integration { + uint8_t reserved[24]; /* 0x00-0x17 */ + struct sdb_product product; /* 0x08-0x3f */ +}; + +/* Type 0x81: Top module repository url + * + * again, an informative field that software can ignore + */ +struct sdb_repo_url { + uint8_t repo_url[63]; /* 0x00-0x3e */ + uint8_t record_type; /* 0x3f */ +}; + +/* Type 0x82: Synthesis tool information + * + * this informative record + */ +struct sdb_synthesis { + uint8_t syn_name[16]; /* 0x00-0x0f */ + uint8_t commit_id[16]; /* 0x10-0x1f */ + uint8_t tool_name[8]; /* 0x20-0x27 */ + uint32_t tool_version; /* 0x28-0x2b */ + uint32_t date; /* 0x2c-0x2f */ + uint8_t user_name[15]; /* 0x30-0x3e */ + uint8_t record_type; /* 0x3f */ +}; + +/* Type 0xff: empty + * + * this allows keeping empty slots during development, + * so they can be filled later with minimal efforts and + * no misleading description is ever shipped -- hopefully. + * It can also be used to pad a table to a desired length. + */ +struct sdb_empty { + uint8_t reserved[63]; /* 0x00-0x3e */ + uint8_t record_type; /* 0x3f */ +}; + +/* The type of bus, for bus-specific flags */ +enum sdb_bus_type { + sdb_wishbone = 0x00, + sdb_data = 0x01, +}; + +#define SDB_WB_WIDTH_MASK 0x0f +#define SDB_WB_ACCESS8 0x01 +#define SDB_WB_ACCESS16 0x02 +#define SDB_WB_ACCESS32 0x04 +#define SDB_WB_ACCESS64 0x08 +#define SDB_WB_LITTLE_ENDIAN 0x80 + +#define SDB_DATA_READ 0x04 +#define SDB_DATA_WRITE 0x02 +#define SDB_DATA_EXEC 0x01 + +#endif /* __SDB_H__ */ diff --git a/include/linux/security.h b/include/linux/security.h index eee7478cda70..5623a7f965b7 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -26,6 +26,7 @@ #include <linux/capability.h> #include <linux/slab.h> #include <linux/err.h> +#include <linux/string.h> struct linux_binprm; struct cred; @@ -60,6 +61,9 @@ struct mm_struct; #define SECURITY_CAP_NOAUDIT 0 #define SECURITY_CAP_AUDIT 1 +/* LSM Agnostic defines for sb_set_mnt_opts */ +#define SECURITY_LSM_NATIVE_LABELS 1 + struct ctl_table; struct audit_krule; struct user_namespace; @@ -306,6 +310,15 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * Parse a string of security data filling in the opts structure * @options string containing all mount options known by the LSM * @opts binary data structure usable by the LSM + * @dentry_init_security: + * Compute a context for a dentry as the inode is not yet available + * since NFSv4 has no label backed by an EA anyway. + * @dentry dentry to use in calculating the context. + * @mode mode used to determine resource type. + * @name name of the last path component used to create file + * @ctx pointer to place the pointer to the resulting context in. + * @ctxlen point to place the length of the resulting context. + * * * Security hooks for inode operations. * @@ -1012,6 +1025,10 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * This hook can be used by the module to update any security state * associated with the TUN device's security structure. * @security pointer to the TUN devices's security structure. + * @skb_owned_by: + * This hook sets the packet's owning sock. + * @skb is the packet. + * @sk the sock which owns the packet. * * Security hooks for XFRM operations. * @@ -1035,17 +1052,25 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * @xfrm_policy_delete_security: * @ctx contains the xfrm_sec_ctx. * Authorize deletion of xp->security. - * @xfrm_state_alloc_security: + * @xfrm_state_alloc: * @x contains the xfrm_state being added to the Security Association * Database by the XFRM system. * @sec_ctx contains the security context information being provided by * the user-level SA generation program (e.g., setkey or racoon). - * @secid contains the secid from which to take the mls portion of the context. * Allocate a security structure to the x->security field; the security * field is initialized to NULL when the xfrm_state is allocated. Set the - * context to correspond to either sec_ctx or polsec, with the mls portion - * taken from secid in the latter case. - * Return 0 if operation was successful (memory to allocate, legal context). + * context to correspond to sec_ctx. Return 0 if operation was successful + * (memory to allocate, legal context). + * @xfrm_state_alloc_acquire: + * @x contains the xfrm_state being added to the Security Association + * Database by the XFRM system. + * @polsec contains the policy's security context. + * @secid contains the secid from which to take the mls portion of the + * context. + * Allocate a security structure to the x->security field; the security + * field is initialized to NULL when the xfrm_state is allocated. Set the + * context to correspond to secid. Return 0 if operation was successful + * (memory to allocate, legal context). * @xfrm_state_free_security: * @x contains the xfrm_state. * Deallocate x->security. @@ -1309,6 +1334,13 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * @pages contains the number of pages. * Return 0 if permission is granted. * + * @ismaclabel: + * Check if the extended attribute specified by @name + * represents a MAC label. Returns 1 if name is a MAC + * attribute otherwise returns 0. + * @name full extended attribute name to check against + * LSM as a MAC label. + * * @secid_to_secctx: * Convert secid to security context. If secdata is NULL the length of * the result will be returned in seclen, but no secdata will be returned. @@ -1388,7 +1420,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * @ctxlen contains the length of @ctx. * * @inode_getsecctx: - * Returns a string containing all relevant security context information + * On success, returns 0 and fills out @ctx and @ctxlen with the security + * context for the given @inode. * * @inode we wish to get the security context of. * @ctx is a pointer in which to place the allocated security context. @@ -1435,10 +1468,16 @@ struct security_operations { int (*sb_pivotroot) (struct path *old_path, struct path *new_path); int (*sb_set_mnt_opts) (struct super_block *sb, - struct security_mnt_opts *opts); - void (*sb_clone_mnt_opts) (const struct super_block *oldsb, + struct security_mnt_opts *opts, + unsigned long kern_flags, + unsigned long *set_kern_flags); + int (*sb_clone_mnt_opts) (const struct super_block *oldsb, struct super_block *newsb); int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts); + int (*dentry_init_security) (struct dentry *dentry, int mode, + struct qstr *name, void **ctx, + u32 *ctxlen); + #ifdef CONFIG_SECURITY_PATH int (*path_unlink) (struct path *dir, struct dentry *dentry); @@ -1461,7 +1500,7 @@ struct security_operations { int (*inode_alloc_security) (struct inode *inode); void (*inode_free_security) (struct inode *inode); int (*inode_init_security) (struct inode *inode, struct inode *dir, - const struct qstr *qstr, char **name, + const struct qstr *qstr, const char **name, void **value, size_t *len); int (*inode_create) (struct inode *dir, struct dentry *dentry, umode_t mode); @@ -1586,6 +1625,7 @@ struct security_operations { int (*getprocattr) (struct task_struct *p, char *name, char **value); int (*setprocattr) (struct task_struct *p, char *name, void *value, size_t size); + int (*ismaclabel) (const char *name); int (*secid_to_secctx) (u32 secid, char **secdata, u32 *seclen); int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid); void (*release_secctx) (char *secdata, u32 seclen); @@ -1638,6 +1678,7 @@ struct security_operations { int (*tun_dev_attach_queue) (void *security); int (*tun_dev_attach) (struct sock *sk, void *security); int (*tun_dev_open) (void *security); + void (*skb_owned_by) (struct sk_buff *skb, struct sock *sk); #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -1646,9 +1687,11 @@ struct security_operations { int (*xfrm_policy_clone_security) (struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctx); void (*xfrm_policy_free_security) (struct xfrm_sec_ctx *ctx); int (*xfrm_policy_delete_security) (struct xfrm_sec_ctx *ctx); - int (*xfrm_state_alloc_security) (struct xfrm_state *x, - struct xfrm_user_sec_ctx *sec_ctx, - u32 secid); + int (*xfrm_state_alloc) (struct xfrm_state *x, + struct xfrm_user_sec_ctx *sec_ctx); + int (*xfrm_state_alloc_acquire) (struct xfrm_state *x, + struct xfrm_sec_ctx *polsec, + u32 secid); void (*xfrm_state_free_security) (struct xfrm_state *x); int (*xfrm_state_delete_security) (struct xfrm_state *x); int (*xfrm_policy_lookup) (struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); @@ -1720,10 +1763,16 @@ int security_sb_mount(const char *dev_name, struct path *path, const char *type, unsigned long flags, void *data); int security_sb_umount(struct vfsmount *mnt, int flags); int security_sb_pivotroot(struct path *old_path, struct path *new_path); -int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts); -void security_sb_clone_mnt_opts(const struct super_block *oldsb, +int security_sb_set_mnt_opts(struct super_block *sb, + struct security_mnt_opts *opts, + unsigned long kern_flags, + unsigned long *set_kern_flags); +int security_sb_clone_mnt_opts(const struct super_block *oldsb, struct super_block *newsb); int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts); +int security_dentry_init_security(struct dentry *dentry, int mode, + struct qstr *name, void **ctx, + u32 *ctxlen); int security_inode_alloc(struct inode *inode); void security_inode_free(struct inode *inode); @@ -1731,7 +1780,7 @@ int security_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, initxattrs initxattrs, void *fs_data); int security_old_inode_init_security(struct inode *inode, struct inode *dir, - const struct qstr *qstr, char **name, + const struct qstr *qstr, const char **name, void **value, size_t *len); int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode); int security_inode_link(struct dentry *old_dentry, struct inode *dir, @@ -1835,6 +1884,7 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode); int security_getprocattr(struct task_struct *p, char *name, char **value); int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size); int security_netlink_send(struct sock *sk, struct sk_buff *skb); +int security_ismaclabel(const char *name); int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); void security_release_secctx(char *secdata, u32 seclen); @@ -2006,14 +2056,18 @@ static inline int security_sb_pivotroot(struct path *old_path, } static inline int security_sb_set_mnt_opts(struct super_block *sb, - struct security_mnt_opts *opts) + struct security_mnt_opts *opts, + unsigned long kern_flags, + unsigned long *set_kern_flags) { return 0; } -static inline void security_sb_clone_mnt_opts(const struct super_block *oldsb, +static inline int security_sb_clone_mnt_opts(const struct super_block *oldsb, struct super_block *newsb) -{ } +{ + return 0; +} static inline int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) { @@ -2028,6 +2082,16 @@ static inline int security_inode_alloc(struct inode *inode) static inline void security_inode_free(struct inode *inode) { } +static inline int security_dentry_init_security(struct dentry *dentry, + int mode, + struct qstr *name, + void **ctx, + u32 *ctxlen) +{ + return -EOPNOTSUPP; +} + + static inline int security_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, @@ -2040,8 +2104,8 @@ static inline int security_inode_init_security(struct inode *inode, static inline int security_old_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, - char **name, void **value, - size_t *len) + const char **name, + void **value, size_t *len) { return -EOPNOTSUPP; } @@ -2513,6 +2577,11 @@ static inline int security_netlink_send(struct sock *sk, struct sk_buff *skb) return cap_netlink_send(sk, skb); } +static inline int security_ismaclabel(const char *name) +{ + return 0; +} + static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) { return -EOPNOTSUPP; @@ -2588,6 +2657,8 @@ int security_tun_dev_attach_queue(void *security); int security_tun_dev_attach(struct sock *sk, void *security); int security_tun_dev_open(void *security); +void security_skb_owned_by(struct sk_buff *skb, struct sock *sk); + #else /* CONFIG_SECURITY_NETWORK */ static inline int security_unix_stream_connect(struct sock *sock, struct sock *other, @@ -2779,6 +2850,11 @@ static inline int security_tun_dev_open(void *security) { return 0; } + +static inline void security_skb_owned_by(struct sk_buff *skb, struct sock *sk) +{ +} + #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM diff --git a/include/linux/sem.h b/include/linux/sem.h index 53d42650b193..976ce3a19f1b 100644 --- a/include/linux/sem.h +++ b/include/linux/sem.h @@ -12,10 +12,12 @@ struct task_struct; struct sem_array { struct kern_ipc_perm ____cacheline_aligned_in_smp sem_perm; /* permissions .. see ipc.h */ - time_t sem_otime; /* last semop time */ time_t sem_ctime; /* last change time */ struct sem *sem_base; /* ptr to first semaphore in array */ - struct list_head sem_pending; /* pending operations to be processed */ + struct list_head pending_alter; /* pending operations */ + /* that alter the array */ + struct list_head pending_const; /* pending complex operations */ + /* that do not alter semvals */ struct list_head list_id; /* undo requests on this array */ int sem_nsems; /* no. of semaphores in array */ int complex_count; /* pending complex operations */ diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 68a04a343cad..4e32edc8f506 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -123,6 +123,7 @@ static inline int seq_nodemask_list(struct seq_file *m, nodemask_t *mask) } int single_open(struct file *, int (*)(struct seq_file *, void *), void *); +int single_open_size(struct file *, int (*)(struct seq_file *, void *), void *, size_t); int single_release(struct inode *, struct file *); void *__seq_open_private(struct file *, const struct seq_operations *, int); int seq_open_private(struct file *, const struct seq_operations *, int); @@ -172,4 +173,10 @@ extern struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head, extern struct hlist_node *seq_hlist_next_rcu(void *v, struct hlist_head *head, loff_t *ppos); + +/* Helpers for iterating over per-cpu hlist_head-s in seq_files */ +extern struct hlist_node *seq_hlist_start_percpu(struct hlist_head __percpu *head, int *cpu, loff_t pos); + +extern struct hlist_node *seq_hlist_next_percpu(void *v, struct hlist_head __percpu *head, int *cpu, loff_t *pos); + #endif diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h index 18299057402f..21a209336e79 100644 --- a/include/linux/seqlock.h +++ b/include/linux/seqlock.h @@ -3,15 +3,21 @@ /* * Reader/writer consistent mechanism without starving writers. This type of * lock for data where the reader wants a consistent set of information - * and is willing to retry if the information changes. Readers never - * block but they may have to retry if a writer is in - * progress. Writers do not wait for readers. + * and is willing to retry if the information changes. There are two types + * of readers: + * 1. Sequence readers which never block a writer but they may have to retry + * if a writer is in progress by detecting change in sequence number. + * Writers do not wait for a sequence reader. + * 2. Locking readers which will wait if a writer or another locking reader + * is in progress. A locking reader in progress will also block a writer + * from going forward. Unlike the regular rwlock, the read lock here is + * exclusive so that only one locking reader can get it. * - * This is not as cache friendly as brlock. Also, this will not work + * This is not as cache friendly as brlock. Also, this may not work well * for data that contains pointers, because any writer could * invalidate a pointer that a reader was following. * - * Expected reader usage: + * Expected non-blocking reader usage: * do { * seq = read_seqbegin(&foo); * ... @@ -268,4 +274,56 @@ write_sequnlock_irqrestore(seqlock_t *sl, unsigned long flags) spin_unlock_irqrestore(&sl->lock, flags); } +/* + * A locking reader exclusively locks out other writers and locking readers, + * but doesn't update the sequence number. Acts like a normal spin_lock/unlock. + * Don't need preempt_disable() because that is in the spin_lock already. + */ +static inline void read_seqlock_excl(seqlock_t *sl) +{ + spin_lock(&sl->lock); +} + +static inline void read_sequnlock_excl(seqlock_t *sl) +{ + spin_unlock(&sl->lock); +} + +static inline void read_seqlock_excl_bh(seqlock_t *sl) +{ + spin_lock_bh(&sl->lock); +} + +static inline void read_sequnlock_excl_bh(seqlock_t *sl) +{ + spin_unlock_bh(&sl->lock); +} + +static inline void read_seqlock_excl_irq(seqlock_t *sl) +{ + spin_lock_irq(&sl->lock); +} + +static inline void read_sequnlock_excl_irq(seqlock_t *sl) +{ + spin_unlock_irq(&sl->lock); +} + +static inline unsigned long __read_seqlock_excl_irqsave(seqlock_t *sl) +{ + unsigned long flags; + + spin_lock_irqsave(&sl->lock, flags); + return flags; +} + +#define read_seqlock_excl_irqsave(lock, flags) \ + do { flags = __read_seqlock_excl_irqsave(lock); } while (0) + +static inline void +read_sequnlock_excl_irqrestore(seqlock_t *sl, unsigned long flags) +{ + spin_unlock_irqrestore(&sl->lock, flags); +} + #endif /* __LINUX_SEQLOCK_H */ diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 87d4bbc773fc..b98291ac7f14 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -31,6 +31,13 @@ #include <linux/sysrq.h> #include <uapi/linux/serial_core.h> +#ifdef CONFIG_SERIAL_CORE_CONSOLE +#define uart_console(port) \ + ((port)->cons && (port)->cons->index == (port)->line) +#else +#define uart_console(port) (0) +#endif + struct uart_port; struct serial_struct; struct device; diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h new file mode 100644 index 000000000000..907d9d1d56cf --- /dev/null +++ b/include/linux/serial_s3c.h @@ -0,0 +1,260 @@ +/* + * Internal header file for Samsung S3C2410 serial ports (UART0-2) + * + * Copyright (C) 2002 Shane Nay (shane@minirl.com) + * + * Additional defines, Copyright 2003 Simtec Electronics (linux@simtec.co.uk) + * + * Adapted from: + * + * Internal header file for MX1ADS serial ports (UART1 & 2) + * + * Copyright (C) 2002 Shane Nay (shane@minirl.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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __ASM_ARM_REGS_SERIAL_H +#define __ASM_ARM_REGS_SERIAL_H + +#define S3C2410_URXH (0x24) +#define S3C2410_UTXH (0x20) +#define S3C2410_ULCON (0x00) +#define S3C2410_UCON (0x04) +#define S3C2410_UFCON (0x08) +#define S3C2410_UMCON (0x0C) +#define S3C2410_UBRDIV (0x28) +#define S3C2410_UTRSTAT (0x10) +#define S3C2410_UERSTAT (0x14) +#define S3C2410_UFSTAT (0x18) +#define S3C2410_UMSTAT (0x1C) + +#define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3)) + +#define S3C2410_LCON_CS5 (0x0) +#define S3C2410_LCON_CS6 (0x1) +#define S3C2410_LCON_CS7 (0x2) +#define S3C2410_LCON_CS8 (0x3) +#define S3C2410_LCON_CSMASK (0x3) + +#define S3C2410_LCON_PNONE (0x0) +#define S3C2410_LCON_PEVEN (0x5 << 3) +#define S3C2410_LCON_PODD (0x4 << 3) +#define S3C2410_LCON_PMASK (0x7 << 3) + +#define S3C2410_LCON_STOPB (1<<2) +#define S3C2410_LCON_IRM (1<<6) + +#define S3C2440_UCON_CLKMASK (3<<10) +#define S3C2440_UCON_CLKSHIFT (10) +#define S3C2440_UCON_PCLK (0<<10) +#define S3C2440_UCON_UCLK (1<<10) +#define S3C2440_UCON_PCLK2 (2<<10) +#define S3C2440_UCON_FCLK (3<<10) +#define S3C2443_UCON_EPLL (3<<10) + +#define S3C6400_UCON_CLKMASK (3<<10) +#define S3C6400_UCON_CLKSHIFT (10) +#define S3C6400_UCON_PCLK (0<<10) +#define S3C6400_UCON_PCLK2 (2<<10) +#define S3C6400_UCON_UCLK0 (1<<10) +#define S3C6400_UCON_UCLK1 (3<<10) + +#define S3C2440_UCON2_FCLK_EN (1<<15) +#define S3C2440_UCON0_DIVMASK (15 << 12) +#define S3C2440_UCON1_DIVMASK (15 << 12) +#define S3C2440_UCON2_DIVMASK (7 << 12) +#define S3C2440_UCON_DIVSHIFT (12) + +#define S3C2412_UCON_CLKMASK (3<<10) +#define S3C2412_UCON_CLKSHIFT (10) +#define S3C2412_UCON_UCLK (1<<10) +#define S3C2412_UCON_USYSCLK (3<<10) +#define S3C2412_UCON_PCLK (0<<10) +#define S3C2412_UCON_PCLK2 (2<<10) + +#define S3C2410_UCON_CLKMASK (1 << 10) +#define S3C2410_UCON_CLKSHIFT (10) +#define S3C2410_UCON_UCLK (1<<10) +#define S3C2410_UCON_SBREAK (1<<4) + +#define S3C2410_UCON_TXILEVEL (1<<9) +#define S3C2410_UCON_RXILEVEL (1<<8) +#define S3C2410_UCON_TXIRQMODE (1<<2) +#define S3C2410_UCON_RXIRQMODE (1<<0) +#define S3C2410_UCON_RXFIFO_TOI (1<<7) +#define S3C2443_UCON_RXERR_IRQEN (1<<6) +#define S3C2443_UCON_LOOPBACK (1<<5) + +#define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ + S3C2410_UCON_RXILEVEL | \ + S3C2410_UCON_TXIRQMODE | \ + S3C2410_UCON_RXIRQMODE | \ + S3C2410_UCON_RXFIFO_TOI) + +#define S3C2410_UFCON_FIFOMODE (1<<0) +#define S3C2410_UFCON_TXTRIG0 (0<<6) +#define S3C2410_UFCON_RXTRIG8 (1<<4) +#define S3C2410_UFCON_RXTRIG12 (2<<4) + +/* S3C2440 FIFO trigger levels */ +#define S3C2440_UFCON_RXTRIG1 (0<<4) +#define S3C2440_UFCON_RXTRIG8 (1<<4) +#define S3C2440_UFCON_RXTRIG16 (2<<4) +#define S3C2440_UFCON_RXTRIG32 (3<<4) + +#define S3C2440_UFCON_TXTRIG0 (0<<6) +#define S3C2440_UFCON_TXTRIG16 (1<<6) +#define S3C2440_UFCON_TXTRIG32 (2<<6) +#define S3C2440_UFCON_TXTRIG48 (3<<6) + +#define S3C2410_UFCON_RESETBOTH (3<<1) +#define S3C2410_UFCON_RESETTX (1<<2) +#define S3C2410_UFCON_RESETRX (1<<1) + +#define S3C2410_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ + S3C2410_UFCON_TXTRIG0 | \ + S3C2410_UFCON_RXTRIG8 ) + +#define S3C2410_UMCOM_AFC (1<<4) +#define S3C2410_UMCOM_RTS_LOW (1<<0) + +#define S3C2412_UMCON_AFC_63 (0<<5) /* same as s3c2443 */ +#define S3C2412_UMCON_AFC_56 (1<<5) +#define S3C2412_UMCON_AFC_48 (2<<5) +#define S3C2412_UMCON_AFC_40 (3<<5) +#define S3C2412_UMCON_AFC_32 (4<<5) +#define S3C2412_UMCON_AFC_24 (5<<5) +#define S3C2412_UMCON_AFC_16 (6<<5) +#define S3C2412_UMCON_AFC_8 (7<<5) + +#define S3C2410_UFSTAT_TXFULL (1<<9) +#define S3C2410_UFSTAT_RXFULL (1<<8) +#define S3C2410_UFSTAT_TXMASK (15<<4) +#define S3C2410_UFSTAT_TXSHIFT (4) +#define S3C2410_UFSTAT_RXMASK (15<<0) +#define S3C2410_UFSTAT_RXSHIFT (0) + +/* UFSTAT S3C2443 same as S3C2440 */ +#define S3C2440_UFSTAT_TXFULL (1<<14) +#define S3C2440_UFSTAT_RXFULL (1<<6) +#define S3C2440_UFSTAT_TXSHIFT (8) +#define S3C2440_UFSTAT_RXSHIFT (0) +#define S3C2440_UFSTAT_TXMASK (63<<8) +#define S3C2440_UFSTAT_RXMASK (63) + +#define S3C2410_UTRSTAT_TXE (1<<2) +#define S3C2410_UTRSTAT_TXFE (1<<1) +#define S3C2410_UTRSTAT_RXDR (1<<0) + +#define S3C2410_UERSTAT_OVERRUN (1<<0) +#define S3C2410_UERSTAT_FRAME (1<<2) +#define S3C2410_UERSTAT_BREAK (1<<3) +#define S3C2443_UERSTAT_PARITY (1<<1) + +#define S3C2410_UERSTAT_ANY (S3C2410_UERSTAT_OVERRUN | \ + S3C2410_UERSTAT_FRAME | \ + S3C2410_UERSTAT_BREAK) + +#define S3C2410_UMSTAT_CTS (1<<0) +#define S3C2410_UMSTAT_DeltaCTS (1<<2) + +#define S3C2443_DIVSLOT (0x2C) + +/* S3C64XX interrupt registers. */ +#define S3C64XX_UINTP 0x30 +#define S3C64XX_UINTSP 0x34 +#define S3C64XX_UINTM 0x38 + +#define S3C64XX_UINTM_RXD (0) +#define S3C64XX_UINTM_TXD (2) +#define S3C64XX_UINTM_RXD_MSK (1 << S3C64XX_UINTM_RXD) +#define S3C64XX_UINTM_TXD_MSK (1 << S3C64XX_UINTM_TXD) + +/* Following are specific to S5PV210 */ +#define S5PV210_UCON_CLKMASK (1<<10) +#define S5PV210_UCON_CLKSHIFT (10) +#define S5PV210_UCON_PCLK (0<<10) +#define S5PV210_UCON_UCLK (1<<10) + +#define S5PV210_UFCON_TXTRIG0 (0<<8) +#define S5PV210_UFCON_TXTRIG4 (1<<8) +#define S5PV210_UFCON_TXTRIG8 (2<<8) +#define S5PV210_UFCON_TXTRIG16 (3<<8) +#define S5PV210_UFCON_TXTRIG32 (4<<8) +#define S5PV210_UFCON_TXTRIG64 (5<<8) +#define S5PV210_UFCON_TXTRIG128 (6<<8) +#define S5PV210_UFCON_TXTRIG256 (7<<8) + +#define S5PV210_UFCON_RXTRIG1 (0<<4) +#define S5PV210_UFCON_RXTRIG4 (1<<4) +#define S5PV210_UFCON_RXTRIG8 (2<<4) +#define S5PV210_UFCON_RXTRIG16 (3<<4) +#define S5PV210_UFCON_RXTRIG32 (4<<4) +#define S5PV210_UFCON_RXTRIG64 (5<<4) +#define S5PV210_UFCON_RXTRIG128 (6<<4) +#define S5PV210_UFCON_RXTRIG256 (7<<4) + +#define S5PV210_UFSTAT_TXFULL (1<<24) +#define S5PV210_UFSTAT_RXFULL (1<<8) +#define S5PV210_UFSTAT_TXMASK (255<<16) +#define S5PV210_UFSTAT_TXSHIFT (16) +#define S5PV210_UFSTAT_RXMASK (255<<0) +#define S5PV210_UFSTAT_RXSHIFT (0) + +#define S3C2410_UCON_CLKSEL0 (1 << 0) +#define S3C2410_UCON_CLKSEL1 (1 << 1) +#define S3C2410_UCON_CLKSEL2 (1 << 2) +#define S3C2410_UCON_CLKSEL3 (1 << 3) + +/* Default values for s5pv210 UCON and UFCON uart registers */ +#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ + S3C2410_UCON_RXILEVEL | \ + S3C2410_UCON_TXIRQMODE | \ + S3C2410_UCON_RXIRQMODE | \ + S3C2410_UCON_RXFIFO_TOI | \ + S3C2443_UCON_RXERR_IRQEN) + +#define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ + S5PV210_UFCON_TXTRIG4 | \ + S5PV210_UFCON_RXTRIG4) + +#ifndef __ASSEMBLY__ + +/* configuration structure for per-machine configurations for the + * serial port + * + * the pointer is setup by the machine specific initialisation from the + * arch/arm/mach-s3c2410/ directory. +*/ + +struct s3c2410_uartcfg { + unsigned char hwport; /* hardware port number */ + unsigned char unused; + unsigned short flags; + upf_t uart_flags; /* default uart flags */ + unsigned int clk_sel; + + unsigned int has_fracval; + + unsigned long ucon; /* value of ucon for port */ + unsigned long ulcon; /* value of ulcon for port */ + unsigned long ufcon; /* value of ufcon for port */ +}; + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_ARM_REGS_SERIAL_H */ + diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index eb763adf9815..3dbdf7e53dcc 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -5,17 +5,22 @@ #include <linux/sh_dma.h> /* - * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) + * Generic header for SuperH (H)SCI(F) (used by sh/sh64 and related parts) */ #define SCIx_NOT_SUPPORTED (-1) enum { + SCBRR_ALGO_INVALID, + SCBRR_ALGO_1, /* ((clk + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_2, /* ((clk + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ + SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */ + + SCBRR_NR_ALGOS, }; #define SCSCR_TIE (1 << 7) @@ -37,7 +42,7 @@ enum { #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) -/* SCxSR SCIF */ +/* SCxSR SCIF, HSCIF */ #define SCIF_ER 0x0080 #define SCIF_TEND 0x0040 #define SCIF_TDFE 0x0020 @@ -55,6 +60,9 @@ enum { #define SCSPTR_SPB2IO (1 << 1) #define SCSPTR_SPB2DT (1 << 0) +/* HSSRR HSCIF */ +#define HSCIF_SRE 0x8000 + /* Offsets into the sci_port->irqs array */ enum { SCIx_ERI_IRQ, @@ -90,6 +98,7 @@ enum { SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH7705_SCIF_REGTYPE, + SCIx_HSCIF_REGTYPE, SCIx_NR_REGTYPES, }; @@ -115,6 +124,7 @@ enum { SCSMR, SCBRR, SCSCR, SCxSR, SCFCR, SCFDR, SCxTDR, SCxRDR, SCLSR, SCTFDR, SCRFDR, SCSPTR, + HSSRR, SCIx_NR_REGS, }; @@ -137,7 +147,7 @@ struct plat_sci_port { unsigned long mapbase; /* resource base */ unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */ - unsigned int type; /* SCI / SCIF / IRDA */ + unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ upf_t flags; /* UPF_* flags */ unsigned long capabilities; /* Port features/capabilities */ diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h index b64d6bec6f90..b7b43b82231e 100644 --- a/include/linux/sh_dma.h +++ b/include/linux/sh_dma.h @@ -33,13 +33,44 @@ struct sh_dmae_slave_config { char mid_rid; }; +/** + * struct sh_dmae_channel - DMAC channel platform data + * @offset: register offset within the main IOMEM resource + * @dmars: channel DMARS register offset + * @chclr_offset: channel CHCLR register offset + * @dmars_bit: channel DMARS field offset within the register + * @chclr_bit: bit position, to be set to reset the channel + */ struct sh_dmae_channel { unsigned int offset; unsigned int dmars; - unsigned int dmars_bit; unsigned int chclr_offset; + unsigned char dmars_bit; + unsigned char chclr_bit; }; +/** + * struct sh_dmae_pdata - DMAC platform data + * @slave: array of slaves + * @slave_num: number of slaves in the above array + * @channel: array of DMA channels + * @channel_num: number of channels in the above array + * @ts_low_shift: shift of the low part of the TS field + * @ts_low_mask: low TS field mask + * @ts_high_shift: additional shift of the high part of the TS field + * @ts_high_mask: high TS field mask + * @ts_shift: array of Transfer Size shifts, indexed by TS value + * @ts_shift_num: number of shifts in the above array + * @dmaor_init: DMAOR initialisation value + * @chcr_offset: CHCR address offset + * @chcr_ie_bit: CHCR Interrupt Enable bit + * @dmaor_is_32bit: DMAOR is a 32-bit register + * @needs_tend_set: the TEND register has to be set + * @no_dmars: DMAC has no DMARS registers + * @chclr_present: DMAC has one or several CHCLR registers + * @chclr_bitwise: channel CHCLR registers are bitwise + * @slave_only: DMAC cannot be used for MEMCPY + */ struct sh_dmae_pdata { const struct sh_dmae_slave_config *slave; int slave_num; @@ -59,46 +90,24 @@ struct sh_dmae_pdata { unsigned int needs_tend_set:1; unsigned int no_dmars:1; unsigned int chclr_present:1; + unsigned int chclr_bitwise:1; unsigned int slave_only:1; }; -/* DMA register */ -#define SAR 0x00 -#define DAR 0x04 -#define TCR 0x08 -#define CHCR 0x0C -#define DMAOR 0x40 - -#define TEND 0x18 /* USB-DMAC */ - /* DMAOR definitions */ #define DMAOR_AE 0x00000004 #define DMAOR_NMIF 0x00000002 #define DMAOR_DME 0x00000001 /* Definitions for the SuperH DMAC */ -#define REQ_L 0x00000000 -#define REQ_E 0x00080000 -#define RACK_H 0x00000000 -#define RACK_L 0x00040000 -#define ACK_R 0x00000000 -#define ACK_W 0x00020000 -#define ACK_H 0x00000000 -#define ACK_L 0x00010000 #define DM_INC 0x00004000 #define DM_DEC 0x00008000 #define DM_FIX 0x0000c000 #define SM_INC 0x00001000 #define SM_DEC 0x00002000 #define SM_FIX 0x00003000 -#define RS_IN 0x00000200 -#define RS_OUT 0x00000300 -#define TS_BLK 0x00000040 -#define TM_BUR 0x00000020 #define CHCR_DE 0x00000001 #define CHCR_TE 0x00000002 #define CHCR_IE 0x00000004 -bool shdma_chan_filter(struct dma_chan *chan, void *arg); - #endif diff --git a/include/linux/sh_eth.h b/include/linux/sh_eth.h index b17d765ded84..90b5e30c2f22 100644 --- a/include/linux/sh_eth.h +++ b/include/linux/sh_eth.h @@ -2,22 +2,17 @@ #define __ASM_SH_ETH_H__ #include <linux/phy.h> +#include <linux/if_ether.h> enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN}; -enum { - SH_ETH_REG_GIGABIT, - SH_ETH_REG_FAST_SH4, - SH_ETH_REG_FAST_SH3_SH2 -}; struct sh_eth_plat_data { int phy; int edmac_endian; - int register_type; phy_interface_t phy_interface; void (*set_mdio_gate)(void *addr); - unsigned char mac_addr[6]; + unsigned char mac_addr[ETH_ALEN]; unsigned no_ether_link:1; unsigned ether_link_active_low:1; unsigned needs_init:1; diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h index a3728bf66f0e..f92c0a43c54c 100644 --- a/include/linux/shdma-base.h +++ b/include/linux/shdma-base.h @@ -68,6 +68,8 @@ struct shdma_chan { int id; /* Raw id of this channel */ int irq; /* Channel IRQ */ int slave_id; /* Client ID for slave DMA */ + int hw_req; /* DMA request line for slave DMA - same + * as MID/RID, used with DT */ enum shdma_pm_state pm_state; }; @@ -94,7 +96,7 @@ struct shdma_ops { dma_addr_t (*slave_addr)(struct shdma_chan *); int (*desc_setup)(struct shdma_chan *, struct shdma_desc *, dma_addr_t, dma_addr_t, size_t *); - int (*set_slave)(struct shdma_chan *, int, bool); + int (*set_slave)(struct shdma_chan *, int, dma_addr_t, bool); void (*setup_xfer)(struct shdma_chan *, int); void (*start_xfer)(struct shdma_chan *, struct shdma_desc *); struct shdma_desc *(*embedded_desc)(void *, int); @@ -114,7 +116,6 @@ struct shdma_dev { int shdma_request_irq(struct shdma_chan *, int, unsigned long, const char *); -void shdma_free_irq(struct shdma_chan *); bool shdma_reset(struct shdma_dev *sdev); void shdma_chan_probe(struct shdma_dev *sdev, struct shdma_chan *schan, int id); @@ -122,5 +123,10 @@ void shdma_chan_remove(struct shdma_chan *schan); int shdma_init(struct device *dev, struct shdma_dev *sdev, int chan_num); void shdma_cleanup(struct shdma_dev *sdev); +#if IS_ENABLED(CONFIG_SH_DMAE_BASE) +bool shdma_chan_filter(struct dma_chan *chan, void *arg); +#else +#define shdma_chan_filter NULL +#endif #endif diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h index ac6b8ee07825..68c097077ef0 100644 --- a/include/linux/shrinker.h +++ b/include/linux/shrinker.h @@ -4,39 +4,67 @@ /* * This struct is used to pass information from page reclaim to the shrinkers. * We consolidate the values for easier extention later. + * + * The 'gfpmask' refers to the allocation we are currently trying to + * fulfil. */ struct shrink_control { gfp_t gfp_mask; - /* How many slab objects shrinker() should scan and try to reclaim */ + /* + * How many objects scan_objects should scan and try to reclaim. + * This is reset before every call, so it is safe for callees + * to modify. + */ unsigned long nr_to_scan; + + /* shrink from these nodes */ + nodemask_t nodes_to_scan; + /* current node being shrunk (for NUMA aware shrinkers) */ + int nid; }; +#define SHRINK_STOP (~0UL) /* * A callback you can register to apply pressure to ageable caches. * - * 'sc' is passed shrink_control which includes a count 'nr_to_scan' - * and a 'gfpmask'. It should look through the least-recently-used - * 'nr_to_scan' entries and attempt to free them up. It should return - * the number of objects which remain in the cache. If it returns -1, it means - * it cannot do any scanning at this time (eg. there is a risk of deadlock). + * @count_objects should return the number of freeable items in the cache. If + * there are no objects to free or the number of freeable items cannot be + * determined, it should return 0. No deadlock checks should be done during the + * count callback - the shrinker relies on aggregating scan counts that couldn't + * be executed due to potential deadlocks to be run at a later call when the + * deadlock condition is no longer pending. * - * The 'gfpmask' refers to the allocation we are currently trying to - * fulfil. + * @scan_objects will only be called if @count_objects returned a non-zero + * value for the number of freeable objects. The callout should scan the cache + * and attempt to free items from the cache. It should then return the number + * of objects freed during the scan, or SHRINK_STOP if progress cannot be made + * due to potential deadlocks. If SHRINK_STOP is returned, then no further + * attempts to call the @scan_objects will be made from the current reclaim + * context. * - * Note that 'shrink' will be passed nr_to_scan == 0 when the VM is - * querying the cache size, so a fastpath for that case is appropriate. + * @flags determine the shrinker abilities, like numa awareness */ struct shrinker { - int (*shrink)(struct shrinker *, struct shrink_control *sc); + unsigned long (*count_objects)(struct shrinker *, + struct shrink_control *sc); + unsigned long (*scan_objects)(struct shrinker *, + struct shrink_control *sc); + int seeks; /* seeks to recreate an obj */ long batch; /* reclaim batch size, 0 = default */ + unsigned long flags; /* These are for internal use */ struct list_head list; - atomic_long_t nr_in_batch; /* objs pending delete */ + /* objs pending delete, per node */ + atomic_long_t *nr_deferred; }; #define DEFAULT_SEEKS 2 /* A good number if you don't know better. */ -extern void register_shrinker(struct shrinker *); + +/* Flags */ +#define SHRINKER_NUMA_AWARE (1 << 0) + +extern int register_shrinker(struct shrinker *); extern void unregister_shrinker(struct shrinker *); #endif diff --git a/include/linux/signal.h b/include/linux/signal.h index a2dcb94ea49d..2ac423bdb676 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -250,11 +250,11 @@ extern int show_unhandled_signals; extern int sigsuspend(sigset_t *); struct sigaction { -#ifndef __ARCH_HAS_ODD_SIGACTION +#ifndef __ARCH_HAS_IRIX_SIGACTION __sighandler_t sa_handler; unsigned long sa_flags; #else - unsigned long sa_flags; + unsigned int sa_flags; __sighandler_t sa_handler; #endif #ifdef __ARCH_HAS_SA_RESTORER @@ -434,4 +434,17 @@ void signals_init(void); int restore_altstack(const stack_t __user *); int __save_altstack(stack_t __user *, unsigned long); +#define save_altstack_ex(uss, sp) do { \ + stack_t __user *__uss = uss; \ + struct task_struct *t = current; \ + put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \ + put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \ + put_user_ex(t->sas_ss_size, &__uss->ss_size); \ +} while (0); + +#ifdef CONFIG_PROC_FS +struct seq_file; +extern void render_sigset_t(struct seq_file *, const char *, sigset_t *); +#endif + #endif /* _LINUX_SIGNAL_H */ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 821c7f45d2a7..2ddb48d9312c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -32,6 +32,7 @@ #include <linux/hrtimer.h> #include <linux/dma-mapping.h> #include <linux/netdev_features.h> +#include <net/flow_keys.h> /* Don't change this without changing skb_csum_unnecessary! */ #define CHECKSUM_NONE 0 @@ -316,6 +317,10 @@ enum { SKB_GSO_FCOE = 1 << 5, SKB_GSO_GRE = 1 << 6, + + SKB_GSO_UDP_TUNNEL = 1 << 7, + + SKB_GSO_MPLS = 1 << 8, }; #if BITS_PER_LONG > 32 @@ -381,12 +386,16 @@ typedef unsigned char *sk_buff_data_t; * @no_fcs: Request NIC to treat last 4 bytes as Ethernet FCS * @dma_cookie: a cookie to one of several possible DMA operations * done by skb DMA functions + * @napi_id: id of the NAPI struct this skb came from * @secmark: security marking * @mark: Generic packet mark * @dropcount: total number of sk_receive_queue overflows + * @vlan_proto: vlan encapsulation protocol * @vlan_tci: vlan tag control information + * @inner_protocol: Protocol (encapsulation) * @inner_transport_header: Inner transport layer header (encapsulation) * @inner_network_header: Network layer header (encapsulation) + * @inner_mac_header: Link layer header (encapsulation) * @transport_header: Transport layer header * @network_header: Network layer header * @mac_header: Link layer header @@ -461,6 +470,7 @@ struct sk_buff { __u32 rxhash; + __be16 vlan_proto; __u16 vlan_tci; #ifdef CONFIG_NET_SCHED @@ -491,8 +501,11 @@ struct sk_buff { /* 7/9 bit hole (depending on ndisc_nodetype presence) */ kmemcheck_bitfield_end(flags2); -#ifdef CONFIG_NET_DMA - dma_cookie_t dma_cookie; +#if defined CONFIG_NET_DMA || defined CONFIG_NET_RX_BUSY_POLL + union { + unsigned int napi_id; + dma_cookie_t dma_cookie; + }; #endif #ifdef CONFIG_NETWORK_SECMARK __u32 secmark; @@ -500,14 +513,16 @@ struct sk_buff { union { __u32 mark; __u32 dropcount; - __u32 avail_size; + __u32 reserved_tailroom; }; - sk_buff_data_t inner_transport_header; - sk_buff_data_t inner_network_header; - sk_buff_data_t transport_header; - sk_buff_data_t network_header; - sk_buff_data_t mac_header; + __be16 inner_protocol; + __u16 inner_transport_header; + __u16 inner_network_header; + __u16 inner_mac_header; + __u16 transport_header; + __u16 network_header; + __u16 mac_header; /* These elements must be at the end, see alloc_skb() for details. */ sk_buff_data_t tail; sk_buff_data_t end; @@ -570,7 +585,40 @@ static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst) skb->_skb_refdst = (unsigned long)dst; } -extern void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst); +extern void __skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst, + bool force); + +/** + * skb_dst_set_noref - sets skb dst, hopefully, without taking reference + * @skb: buffer + * @dst: dst entry + * + * Sets skb dst, assuming a reference was not taken on dst. + * If dst entry is cached, we do not take reference and dst_release + * will be avoided by refdst_drop. If dst entry is not cached, we take + * reference, so that last dst_release can destroy the dst immediately. + */ +static inline void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst) +{ + __skb_dst_set_noref(skb, dst, false); +} + +/** + * skb_dst_set_noref_force - sets skb dst, without taking reference + * @skb: buffer + * @dst: dst entry + * + * Sets skb dst, assuming a reference was not taken on dst. + * No reference is taken and no dst_release will be called. While for + * cached dsts deferred reclaim is a basic feature, for entries that are + * not cached it is caller's job to guarantee that last dst_release for + * provided dst happens when nobody uses it, eg. after a RCU grace period. + */ +static inline void skb_dst_set_noref_force(struct sk_buff *skb, + struct dst_entry *dst) +{ + __skb_dst_set_noref(skb, dst, true); +} /** * skb_dst_is_noref - Test if skb dst isn't refcounted @@ -587,6 +635,7 @@ static inline struct rtable *skb_rtable(const struct sk_buff *skb) } extern void kfree_skb(struct sk_buff *skb); +extern void kfree_skb_list(struct sk_buff *segs); extern void skb_tx_error(struct sk_buff *skb); extern void consume_skb(struct sk_buff *skb); extern void __kfree_skb(struct sk_buff *skb); @@ -611,6 +660,12 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size, return __alloc_skb(size, priority, SKB_ALLOC_FCLONE, NUMA_NO_NODE); } +extern struct sk_buff *__alloc_skb_head(gfp_t priority, int node); +static inline struct sk_buff *alloc_skb_head(gfp_t priority) +{ + return __alloc_skb_head(priority, -1); +} + extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src); extern int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask); extern struct sk_buff *skb_clone(struct sk_buff *skb, @@ -1288,11 +1343,13 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i, * do not lose pfmemalloc information as the pages would not be * allocated using __GFP_MEMALLOC. */ - if (page->pfmemalloc && !page->mapping) - skb->pfmemalloc = true; frag->page.p = page; frag->page_offset = off; skb_frag_size_set(frag, size); + + page = compound_head(page); + if (page->pfmemalloc && !page->mapping) + skb->pfmemalloc = true; } /** @@ -1339,6 +1396,7 @@ static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset) skb_reset_tail_pointer(skb); skb->tail += offset; } + #else /* NET_SKBUFF_DATA_USES_OFFSET */ static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb) { @@ -1447,7 +1505,10 @@ static inline int skb_tailroom(const struct sk_buff *skb) */ static inline int skb_availroom(const struct sk_buff *skb) { - return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len; + if (skb_is_nonlinear(skb)) + return 0; + + return skb->end - skb->tail - skb->reserved_tailroom; } /** @@ -1466,6 +1527,7 @@ static inline void skb_reserve(struct sk_buff *skb, int len) static inline void skb_reset_inner_headers(struct sk_buff *skb) { + skb->inner_mac_header = skb->mac_header; skb->inner_network_header = skb->network_header; skb->inner_transport_header = skb->transport_header; } @@ -1475,7 +1537,6 @@ static inline void skb_reset_mac_len(struct sk_buff *skb) skb->mac_len = skb->network_header - skb->mac_header; } -#ifdef NET_SKBUFF_DATA_USES_OFFSET static inline unsigned char *skb_inner_transport_header(const struct sk_buff *skb) { @@ -1511,9 +1572,25 @@ static inline void skb_set_inner_network_header(struct sk_buff *skb, skb->inner_network_header += offset; } +static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb) +{ + return skb->head + skb->inner_mac_header; +} + +static inline void skb_reset_inner_mac_header(struct sk_buff *skb) +{ + skb->inner_mac_header = skb->data - skb->head; +} + +static inline void skb_set_inner_mac_header(struct sk_buff *skb, + const int offset) +{ + skb_reset_inner_mac_header(skb); + skb->inner_mac_header += offset; +} static inline bool skb_transport_header_was_set(const struct sk_buff *skb) { - return skb->transport_header != ~0U; + return skb->transport_header != (typeof(skb->transport_header))~0U; } static inline unsigned char *skb_transport_header(const struct sk_buff *skb) @@ -1556,7 +1633,7 @@ static inline unsigned char *skb_mac_header(const struct sk_buff *skb) static inline int skb_mac_header_was_set(const struct sk_buff *skb) { - return skb->mac_header != ~0U; + return skb->mac_header != (typeof(skb->mac_header))~0U; } static inline void skb_reset_mac_header(struct sk_buff *skb) @@ -1570,97 +1647,19 @@ static inline void skb_set_mac_header(struct sk_buff *skb, const int offset) skb->mac_header += offset; } -#else /* NET_SKBUFF_DATA_USES_OFFSET */ -static inline unsigned char *skb_inner_transport_header(const struct sk_buff - *skb) -{ - return skb->inner_transport_header; -} - -static inline void skb_reset_inner_transport_header(struct sk_buff *skb) -{ - skb->inner_transport_header = skb->data; -} - -static inline void skb_set_inner_transport_header(struct sk_buff *skb, - const int offset) -{ - skb->inner_transport_header = skb->data + offset; -} - -static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb) -{ - return skb->inner_network_header; -} - -static inline void skb_reset_inner_network_header(struct sk_buff *skb) -{ - skb->inner_network_header = skb->data; -} - -static inline void skb_set_inner_network_header(struct sk_buff *skb, - const int offset) -{ - skb->inner_network_header = skb->data + offset; -} - -static inline bool skb_transport_header_was_set(const struct sk_buff *skb) -{ - return skb->transport_header != NULL; -} - -static inline unsigned char *skb_transport_header(const struct sk_buff *skb) -{ - return skb->transport_header; -} - -static inline void skb_reset_transport_header(struct sk_buff *skb) -{ - skb->transport_header = skb->data; -} - -static inline void skb_set_transport_header(struct sk_buff *skb, - const int offset) -{ - skb->transport_header = skb->data + offset; -} - -static inline unsigned char *skb_network_header(const struct sk_buff *skb) -{ - return skb->network_header; -} - -static inline void skb_reset_network_header(struct sk_buff *skb) +static inline void skb_probe_transport_header(struct sk_buff *skb, + const int offset_hint) { - skb->network_header = skb->data; -} + struct flow_keys keys; -static inline void skb_set_network_header(struct sk_buff *skb, const int offset) -{ - skb->network_header = skb->data + offset; -} - -static inline unsigned char *skb_mac_header(const struct sk_buff *skb) -{ - return skb->mac_header; -} - -static inline int skb_mac_header_was_set(const struct sk_buff *skb) -{ - return skb->mac_header != NULL; -} - -static inline void skb_reset_mac_header(struct sk_buff *skb) -{ - skb->mac_header = skb->data; + if (skb_transport_header_was_set(skb)) + return; + else if (skb_flow_dissect(skb, &keys)) + skb_set_transport_header(skb, keys.thoff); + else + skb_set_transport_header(skb, offset_hint); } -static inline void skb_set_mac_header(struct sk_buff *skb, const int offset) -{ - skb->mac_header = skb->data + offset; -} -#endif /* NET_SKBUFF_DATA_USES_OFFSET */ - static inline void skb_mac_header_rebuild(struct sk_buff *skb) { if (skb_mac_header_was_set(skb)) { @@ -1806,10 +1805,13 @@ static inline void pskb_trim_unique(struct sk_buff *skb, unsigned int len) */ static inline void skb_orphan(struct sk_buff *skb) { - if (skb->destructor) + if (skb->destructor) { skb->destructor(skb); - skb->destructor = NULL; - skb->sk = NULL; + skb->destructor = NULL; + skb->sk = NULL; + } else { + BUG_ON(skb->sk); + } } /** @@ -1903,8 +1905,8 @@ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, return __netdev_alloc_skb_ip_align(dev, length, GFP_ATOMIC); } -/* - * __skb_alloc_page - allocate pages for ps-rx on a skb and preserve pfmemalloc data +/** + * __skb_alloc_pages - allocate pages for ps-rx on a skb and preserve pfmemalloc data * @gfp_mask: alloc_pages_node mask. Set __GFP_NOMEMALLOC if not for network packet RX * @skb: skb to set pfmemalloc on if __GFP_MEMALLOC is used * @order: size of the allocation @@ -2357,6 +2359,10 @@ extern int skb_copy_datagram_from_iovec(struct sk_buff *skb, const struct iovec *from, int from_offset, int len); +extern int zerocopy_sg_from_iovec(struct sk_buff *skb, + const struct iovec *frm, + int offset, + size_t count); extern int skb_copy_datagram_const_iovec(const struct sk_buff *from, int offset, const struct iovec *to, @@ -2386,6 +2392,7 @@ extern void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len); extern int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen); +extern void skb_scrub_packet(struct sk_buff *skb, bool xnet); extern struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features); @@ -2638,6 +2645,13 @@ static inline void nf_reset(struct sk_buff *skb) #endif } +static inline void nf_reset_trace(struct sk_buff *skb) +{ +#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) + skb->nf_trace = 0; +#endif +} + /* Note: This doesn't put any conntrack and bridge info in dst. */ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src) { @@ -2749,6 +2763,21 @@ static inline int skb_tnl_header_len(const struct sk_buff *inner_skb) SKB_GSO_CB(inner_skb)->mac_offset; } +static inline int gso_pskb_expand_head(struct sk_buff *skb, int extra) +{ + int new_headroom, headroom; + int ret; + + headroom = skb_headroom(skb); + ret = pskb_expand_head(skb, extra, 0, GFP_ATOMIC); + if (ret) + return ret; + + new_headroom = skb_headroom(skb); + SKB_GSO_CB(skb)->mac_offset += (new_headroom - headroom); + return 0; +} + static inline bool skb_is_gso(const struct sk_buff *skb) { return skb_shinfo(skb)->gso_size; @@ -2799,6 +2828,8 @@ static inline void skb_checksum_none_assert(const struct sk_buff *skb) bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off); +u32 __skb_get_poff(const struct sk_buff *skb); + /** * skb_head_is_locked - Determine if the skb->head is locked down * @skb: skb to check diff --git a/include/linux/slab.h b/include/linux/slab.h index 5d168d7e0a28..74f105847d13 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -4,6 +4,8 @@ * (C) SGI 2006, Christoph Lameter * Cleaned up and restructured to ease the addition of alternative * implementations of SLAB allocators. + * (C) Linux Foundation 2008-2013 + * Unified interface for all slab allocators */ #ifndef _LINUX_SLAB_H @@ -94,29 +96,7 @@ #define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \ (unsigned long)ZERO_SIZE_PTR) -/* - * Common fields provided in kmem_cache by all slab allocators - * This struct is either used directly by the allocator (SLOB) - * or the allocator must include definitions for all fields - * provided in kmem_cache_common in their definition of kmem_cache. - * - * Once we can do anonymous structs (C11 standard) we could put a - * anonymous struct definition in these allocators so that the - * separate allocations in the kmem_cache structure of SLAB and - * SLUB is no longer needed. - */ -#ifdef CONFIG_SLOB -struct kmem_cache { - unsigned int object_size;/* The original size of the object */ - unsigned int size; /* The aligned/padded/added on size */ - unsigned int align; /* Alignment as calculated */ - unsigned long flags; /* Active flags on the slab */ - const char *name; /* Slab name for sysfs */ - int refcount; /* Use counter */ - void (*ctor)(void *); /* Called on object slot creation */ - struct list_head list; /* List of all slab caches on the system */ -}; -#endif +#include <linux/kmemleak.h> struct mem_cgroup; /* @@ -148,7 +128,59 @@ void kmem_cache_free(struct kmem_cache *, void *); (__flags), NULL) /* - * The largest kmalloc size supported by the slab allocators is + * Common kmalloc functions provided by all allocators + */ +void * __must_check __krealloc(const void *, size_t, gfp_t); +void * __must_check krealloc(const void *, size_t, gfp_t); +void kfree(const void *); +void kzfree(const void *); +size_t ksize(const void *); + +/* + * Some archs want to perform DMA into kmalloc caches and need a guaranteed + * alignment larger than the alignment of a 64-bit integer. + * Setting ARCH_KMALLOC_MINALIGN in arch headers allows that. + */ +#if defined(ARCH_DMA_MINALIGN) && ARCH_DMA_MINALIGN > 8 +#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN +#define KMALLOC_MIN_SIZE ARCH_DMA_MINALIGN +#define KMALLOC_SHIFT_LOW ilog2(ARCH_DMA_MINALIGN) +#else +#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long) +#endif + +#ifdef CONFIG_SLOB +/* + * Common fields provided in kmem_cache by all slab allocators + * This struct is either used directly by the allocator (SLOB) + * or the allocator must include definitions for all fields + * provided in kmem_cache_common in their definition of kmem_cache. + * + * Once we can do anonymous structs (C11 standard) we could put a + * anonymous struct definition in these allocators so that the + * separate allocations in the kmem_cache structure of SLAB and + * SLUB is no longer needed. + */ +struct kmem_cache { + unsigned int object_size;/* The original size of the object */ + unsigned int size; /* The aligned/padded/added on size */ + unsigned int align; /* Alignment as calculated */ + unsigned long flags; /* Active flags on the slab */ + const char *name; /* Slab name for sysfs */ + int refcount; /* Use counter */ + void (*ctor)(void *); /* Called on object slot creation */ + struct list_head list; /* List of all slab caches on the system */ +}; + +#endif /* CONFIG_SLOB */ + +/* + * Kmalloc array related definitions + */ + +#ifdef CONFIG_SLAB +/* + * The largest kmalloc size supported by the SLAB allocators is * 32 megabyte (2^25) or the maximum allocatable page order if that is * less than 32 MB. * @@ -158,21 +190,259 @@ void kmem_cache_free(struct kmem_cache *, void *); */ #define KMALLOC_SHIFT_HIGH ((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \ (MAX_ORDER + PAGE_SHIFT - 1) : 25) +#define KMALLOC_SHIFT_MAX KMALLOC_SHIFT_HIGH +#ifndef KMALLOC_SHIFT_LOW +#define KMALLOC_SHIFT_LOW 5 +#endif +#endif -#define KMALLOC_MAX_SIZE (1UL << KMALLOC_SHIFT_HIGH) -#define KMALLOC_MAX_ORDER (KMALLOC_SHIFT_HIGH - PAGE_SHIFT) +#ifdef CONFIG_SLUB +/* + * SLUB allocates up to order 2 pages directly and otherwise + * passes the request to the page allocator. + */ +#define KMALLOC_SHIFT_HIGH (PAGE_SHIFT + 1) +#define KMALLOC_SHIFT_MAX (MAX_ORDER + PAGE_SHIFT) +#ifndef KMALLOC_SHIFT_LOW +#define KMALLOC_SHIFT_LOW 3 +#endif +#endif +#ifdef CONFIG_SLOB /* - * Some archs want to perform DMA into kmalloc caches and need a guaranteed - * alignment larger than the alignment of a 64-bit integer. - * Setting ARCH_KMALLOC_MINALIGN in arch headers allows that. + * SLOB passes all page size and larger requests to the page allocator. + * No kmalloc array is necessary since objects of different sizes can + * be allocated from the same page. */ -#ifdef ARCH_DMA_MINALIGN -#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN +#define KMALLOC_SHIFT_MAX 30 +#define KMALLOC_SHIFT_HIGH PAGE_SHIFT +#ifndef KMALLOC_SHIFT_LOW +#define KMALLOC_SHIFT_LOW 3 +#endif +#endif + +/* Maximum allocatable size */ +#define KMALLOC_MAX_SIZE (1UL << KMALLOC_SHIFT_MAX) +/* Maximum size for which we actually use a slab cache */ +#define KMALLOC_MAX_CACHE_SIZE (1UL << KMALLOC_SHIFT_HIGH) +/* Maximum order allocatable via the slab allocagtor */ +#define KMALLOC_MAX_ORDER (KMALLOC_SHIFT_MAX - PAGE_SHIFT) + +/* + * Kmalloc subsystem. + */ +#ifndef KMALLOC_MIN_SIZE +#define KMALLOC_MIN_SIZE (1 << KMALLOC_SHIFT_LOW) +#endif + +#ifndef CONFIG_SLOB +extern struct kmem_cache *kmalloc_caches[KMALLOC_SHIFT_HIGH + 1]; +#ifdef CONFIG_ZONE_DMA +extern struct kmem_cache *kmalloc_dma_caches[KMALLOC_SHIFT_HIGH + 1]; +#endif + +/* + * Figure out which kmalloc slab an allocation of a certain size + * belongs to. + * 0 = zero alloc + * 1 = 65 .. 96 bytes + * 2 = 120 .. 192 bytes + * n = 2^(n-1) .. 2^n -1 + */ +static __always_inline int kmalloc_index(size_t size) +{ + if (!size) + return 0; + + if (size <= KMALLOC_MIN_SIZE) + return KMALLOC_SHIFT_LOW; + + if (KMALLOC_MIN_SIZE <= 32 && size > 64 && size <= 96) + return 1; + if (KMALLOC_MIN_SIZE <= 64 && size > 128 && size <= 192) + return 2; + if (size <= 8) return 3; + if (size <= 16) return 4; + if (size <= 32) return 5; + if (size <= 64) return 6; + if (size <= 128) return 7; + if (size <= 256) return 8; + if (size <= 512) return 9; + if (size <= 1024) return 10; + if (size <= 2 * 1024) return 11; + if (size <= 4 * 1024) return 12; + if (size <= 8 * 1024) return 13; + if (size <= 16 * 1024) return 14; + if (size <= 32 * 1024) return 15; + if (size <= 64 * 1024) return 16; + if (size <= 128 * 1024) return 17; + if (size <= 256 * 1024) return 18; + if (size <= 512 * 1024) return 19; + if (size <= 1024 * 1024) return 20; + if (size <= 2 * 1024 * 1024) return 21; + if (size <= 4 * 1024 * 1024) return 22; + if (size <= 8 * 1024 * 1024) return 23; + if (size <= 16 * 1024 * 1024) return 24; + if (size <= 32 * 1024 * 1024) return 25; + if (size <= 64 * 1024 * 1024) return 26; + BUG(); + + /* Will never be reached. Needed because the compiler may complain */ + return -1; +} +#endif /* !CONFIG_SLOB */ + +void *__kmalloc(size_t size, gfp_t flags); +void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags); + +#ifdef CONFIG_NUMA +void *__kmalloc_node(size_t size, gfp_t flags, int node); +void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); #else -#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long) +static __always_inline void *__kmalloc_node(size_t size, gfp_t flags, int node) +{ + return __kmalloc(size, flags); +} + +static __always_inline void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t flags, int node) +{ + return kmem_cache_alloc(s, flags); +} #endif +#ifdef CONFIG_TRACING +extern void *kmem_cache_alloc_trace(struct kmem_cache *, gfp_t, size_t); + +#ifdef CONFIG_NUMA +extern void *kmem_cache_alloc_node_trace(struct kmem_cache *s, + gfp_t gfpflags, + int node, size_t size); +#else +static __always_inline void * +kmem_cache_alloc_node_trace(struct kmem_cache *s, + gfp_t gfpflags, + int node, size_t size) +{ + return kmem_cache_alloc_trace(s, gfpflags, size); +} +#endif /* CONFIG_NUMA */ + +#else /* CONFIG_TRACING */ +static __always_inline void *kmem_cache_alloc_trace(struct kmem_cache *s, + gfp_t flags, size_t size) +{ + return kmem_cache_alloc(s, flags); +} + +static __always_inline void * +kmem_cache_alloc_node_trace(struct kmem_cache *s, + gfp_t gfpflags, + int node, size_t size) +{ + return kmem_cache_alloc_node(s, gfpflags, node); +} +#endif /* CONFIG_TRACING */ + +#ifdef CONFIG_SLAB +#include <linux/slab_def.h> +#endif + +#ifdef CONFIG_SLUB +#include <linux/slub_def.h> +#endif + +static __always_inline void * +kmalloc_order(size_t size, gfp_t flags, unsigned int order) +{ + void *ret; + + flags |= (__GFP_COMP | __GFP_KMEMCG); + ret = (void *) __get_free_pages(flags, order); + kmemleak_alloc(ret, size, 1, flags); + return ret; +} + +#ifdef CONFIG_TRACING +extern void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order); +#else +static __always_inline void * +kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) +{ + return kmalloc_order(size, flags, order); +} +#endif + +static __always_inline void *kmalloc_large(size_t size, gfp_t flags) +{ + unsigned int order = get_order(size); + return kmalloc_order_trace(size, flags, order); +} + +/** + * kmalloc - allocate memory + * @size: how many bytes of memory are required. + * @flags: the type of memory to allocate (see kcalloc). + * + * kmalloc is the normal method of allocating memory + * for objects smaller than page size in the kernel. + */ +static __always_inline void *kmalloc(size_t size, gfp_t flags) +{ + if (__builtin_constant_p(size)) { + if (size > KMALLOC_MAX_CACHE_SIZE) + return kmalloc_large(size, flags); +#ifndef CONFIG_SLOB + if (!(flags & GFP_DMA)) { + int index = kmalloc_index(size); + + if (!index) + return ZERO_SIZE_PTR; + + return kmem_cache_alloc_trace(kmalloc_caches[index], + flags, size); + } +#endif + } + return __kmalloc(size, flags); +} + +/* + * Determine size used for the nth kmalloc cache. + * return size or 0 if a kmalloc cache for that + * size does not exist + */ +static __always_inline int kmalloc_size(int n) +{ +#ifndef CONFIG_SLOB + if (n > 2) + return 1 << n; + + if (n == 1 && KMALLOC_MIN_SIZE <= 32) + return 96; + + if (n == 2 && KMALLOC_MIN_SIZE <= 64) + return 192; +#endif + return 0; +} + +static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) +{ +#ifndef CONFIG_SLOB + if (__builtin_constant_p(size) && + size <= KMALLOC_MAX_CACHE_SIZE && !(flags & GFP_DMA)) { + int i = kmalloc_index(size); + + if (!i) + return ZERO_SIZE_PTR; + + return kmem_cache_alloc_node_trace(kmalloc_caches[i], + flags, node, size); + } +#endif + return __kmalloc_node(size, flags, node); +} + /* * Setting ARCH_SLAB_MINALIGN in arch headers allows a different alignment. * Intended for arches that get misalignment faults even for 64 bit integer @@ -224,46 +494,9 @@ struct seq_file; int cache_show(struct kmem_cache *s, struct seq_file *m); void print_slabinfo_header(struct seq_file *m); -/* - * Common kmalloc functions provided by all allocators - */ -void * __must_check __krealloc(const void *, size_t, gfp_t); -void * __must_check krealloc(const void *, size_t, gfp_t); -void kfree(const void *); -void kzfree(const void *); -size_t ksize(const void *); - -/* - * Allocator specific definitions. These are mainly used to establish optimized - * ways to convert kmalloc() calls to kmem_cache_alloc() invocations by - * selecting the appropriate general cache at compile time. - * - * Allocators must define at least: - * - * kmem_cache_alloc() - * __kmalloc() - * kmalloc() - * - * Those wishing to support NUMA must also define: - * - * kmem_cache_alloc_node() - * kmalloc_node() - * - * See each allocator definition file for additional comments and - * implementation notes. - */ -#ifdef CONFIG_SLUB -#include <linux/slub_def.h> -#elif defined(CONFIG_SLOB) -#include <linux/slob_def.h> -#else -#include <linux/slab_def.h> -#endif - /** - * kmalloc_array - allocate memory for an array. - * @n: number of elements. - * @size: element size. + * kmalloc - allocate memory + * @size: how many bytes of memory are required. * @flags: the type of memory to allocate. * * The @flags argument may be one of: @@ -310,6 +543,17 @@ size_t ksize(const void *); * There are other flags available as well, but these are not intended * for general use, and so are not documented here. For a full list of * potential flags, always refer to linux/gfp.h. + * + * kmalloc is the normal method of allocating memory + * in the kernel. + */ +static __always_inline void *kmalloc(size_t size, gfp_t flags); + +/** + * kmalloc_array - allocate memory for an array. + * @n: number of elements. + * @size: element size. + * @flags: the type of memory to allocate (see kmalloc). */ static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) { @@ -329,36 +573,6 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags) return kmalloc_array(n, size, flags | __GFP_ZERO); } -#if !defined(CONFIG_NUMA) && !defined(CONFIG_SLOB) -/** - * kmalloc_node - allocate memory from a specific node - * @size: how many bytes of memory are required. - * @flags: the type of memory to allocate (see kcalloc). - * @node: node to allocate from. - * - * kmalloc() for non-local nodes, used to allocate from a specific node - * if available. Equivalent to kmalloc() in the non-NUMA single-node - * case. - */ -static inline void *kmalloc_node(size_t size, gfp_t flags, int node) -{ - return kmalloc(size, flags); -} - -static inline void *__kmalloc_node(size_t size, gfp_t flags, int node) -{ - return __kmalloc(size, flags); -} - -void *kmem_cache_alloc(struct kmem_cache *, gfp_t); - -static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep, - gfp_t flags, int node) -{ - return kmem_cache_alloc(cachep, flags); -} -#endif /* !CONFIG_NUMA && !CONFIG_SLOB */ - /* * kmalloc_track_caller is a special version of kmalloc that records the * calling function of the routine calling it for slab leak tracking instead diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index 8bb6e0eaf3c6..e9346b4f1ef4 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h @@ -3,22 +3,6 @@ /* * Definitions unique to the original Linux SLAB allocator. - * - * What we provide here is a way to optimize the frequent kmalloc - * calls in the kernel by selecting the appropriate general cache - * if kmalloc was called with a size that can be established at - * compile time. - */ - -#include <linux/init.h> -#include <asm/page.h> /* kmalloc_sizes.h needs PAGE_SIZE */ -#include <asm/cache.h> /* kmalloc_sizes.h needs L1_CACHE_BYTES */ -#include <linux/compiler.h> - -/* - * struct kmem_cache - * - * manages a cache. */ struct kmem_cache { @@ -97,121 +81,11 @@ struct kmem_cache { * pointer for each node since "nodelists" uses the remainder of * available pointers. */ - struct kmem_list3 **nodelists; + struct kmem_cache_node **node; struct array_cache *array[NR_CPUS + MAX_NUMNODES]; /* * Do not add fields after array[] */ }; -/* Size description struct for general caches. */ -struct cache_sizes { - size_t cs_size; - struct kmem_cache *cs_cachep; -#ifdef CONFIG_ZONE_DMA - struct kmem_cache *cs_dmacachep; -#endif -}; -extern struct cache_sizes malloc_sizes[]; - -void *kmem_cache_alloc(struct kmem_cache *, gfp_t); -void *__kmalloc(size_t size, gfp_t flags); - -#ifdef CONFIG_TRACING -extern void *kmem_cache_alloc_trace(struct kmem_cache *, gfp_t, size_t); -#else -static __always_inline void * -kmem_cache_alloc_trace(struct kmem_cache *cachep, gfp_t flags, size_t size) -{ - return kmem_cache_alloc(cachep, flags); -} -#endif - -static __always_inline void *kmalloc(size_t size, gfp_t flags) -{ - struct kmem_cache *cachep; - void *ret; - - if (__builtin_constant_p(size)) { - int i = 0; - - if (!size) - return ZERO_SIZE_PTR; - -#define CACHE(x) \ - if (size <= x) \ - goto found; \ - else \ - i++; -#include <linux/kmalloc_sizes.h> -#undef CACHE - return NULL; -found: -#ifdef CONFIG_ZONE_DMA - if (flags & GFP_DMA) - cachep = malloc_sizes[i].cs_dmacachep; - else -#endif - cachep = malloc_sizes[i].cs_cachep; - - ret = kmem_cache_alloc_trace(cachep, flags, size); - - return ret; - } - return __kmalloc(size, flags); -} - -#ifdef CONFIG_NUMA -extern void *__kmalloc_node(size_t size, gfp_t flags, int node); -extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); - -#ifdef CONFIG_TRACING -extern void *kmem_cache_alloc_node_trace(struct kmem_cache *cachep, - gfp_t flags, - int nodeid, - size_t size); -#else -static __always_inline void * -kmem_cache_alloc_node_trace(struct kmem_cache *cachep, - gfp_t flags, - int nodeid, - size_t size) -{ - return kmem_cache_alloc_node(cachep, flags, nodeid); -} -#endif - -static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) -{ - struct kmem_cache *cachep; - - if (__builtin_constant_p(size)) { - int i = 0; - - if (!size) - return ZERO_SIZE_PTR; - -#define CACHE(x) \ - if (size <= x) \ - goto found; \ - else \ - i++; -#include <linux/kmalloc_sizes.h> -#undef CACHE - return NULL; -found: -#ifdef CONFIG_ZONE_DMA - if (flags & GFP_DMA) - cachep = malloc_sizes[i].cs_dmacachep; - else -#endif - cachep = malloc_sizes[i].cs_cachep; - - return kmem_cache_alloc_node_trace(cachep, flags, node, size); - } - return __kmalloc_node(size, flags, node); -} - -#endif /* CONFIG_NUMA */ - #endif /* _LINUX_SLAB_DEF_H */ diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h deleted file mode 100644 index f28e14a12e3f..000000000000 --- a/include/linux/slob_def.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __LINUX_SLOB_DEF_H -#define __LINUX_SLOB_DEF_H - -#include <linux/numa.h> - -void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); - -static __always_inline void *kmem_cache_alloc(struct kmem_cache *cachep, - gfp_t flags) -{ - return kmem_cache_alloc_node(cachep, flags, NUMA_NO_NODE); -} - -void *__kmalloc_node(size_t size, gfp_t flags, int node); - -static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) -{ - return __kmalloc_node(size, flags, node); -} - -/** - * kmalloc - allocate memory - * @size: how many bytes of memory are required. - * @flags: the type of memory to allocate (see kcalloc). - * - * kmalloc is the normal method of allocating memory - * in the kernel. - */ -static __always_inline void *kmalloc(size_t size, gfp_t flags) -{ - return __kmalloc_node(size, flags, NUMA_NO_NODE); -} - -static __always_inline void *__kmalloc(size_t size, gfp_t flags) -{ - return kmalloc(size, flags); -} - -#endif /* __LINUX_SLOB_DEF_H */ diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 9db4825cd393..cc0b67eada42 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -6,14 +6,8 @@ * * (C) 2007 SGI, Christoph Lameter */ -#include <linux/types.h> -#include <linux/gfp.h> -#include <linux/bug.h> -#include <linux/workqueue.h> #include <linux/kobject.h> -#include <linux/kmemleak.h> - enum stat_item { ALLOC_FASTPATH, /* Allocation from cpu slab */ ALLOC_SLOWPATH, /* Allocation by getting a new cpu slab */ @@ -53,17 +47,6 @@ struct kmem_cache_cpu { #endif }; -struct kmem_cache_node { - spinlock_t list_lock; /* Protect partial list and nr_partial */ - unsigned long nr_partial; - struct list_head partial; -#ifdef CONFIG_SLUB_DEBUG - atomic_long_t nr_slabs; - atomic_long_t total_objects; - struct list_head full; -#endif -}; - /* * Word size structure that can be atomically updated or read and that * contains both the order and the number of objects that a slab of the @@ -115,211 +98,4 @@ struct kmem_cache { struct kmem_cache_node *node[MAX_NUMNODES]; }; -/* - * Kmalloc subsystem. - */ -#if defined(ARCH_DMA_MINALIGN) && ARCH_DMA_MINALIGN > 8 -#define KMALLOC_MIN_SIZE ARCH_DMA_MINALIGN -#else -#define KMALLOC_MIN_SIZE 8 -#endif - -#define KMALLOC_SHIFT_LOW ilog2(KMALLOC_MIN_SIZE) - -/* - * Maximum kmalloc object size handled by SLUB. Larger object allocations - * are passed through to the page allocator. The page allocator "fastpath" - * is relatively slow so we need this value sufficiently high so that - * performance critical objects are allocated through the SLUB fastpath. - * - * This should be dropped to PAGE_SIZE / 2 once the page allocator - * "fastpath" becomes competitive with the slab allocator fastpaths. - */ -#define SLUB_MAX_SIZE (2 * PAGE_SIZE) - -#define SLUB_PAGE_SHIFT (PAGE_SHIFT + 2) - -#ifdef CONFIG_ZONE_DMA -#define SLUB_DMA __GFP_DMA -#else -/* Disable DMA functionality */ -#define SLUB_DMA (__force gfp_t)0 -#endif - -/* - * We keep the general caches in an array of slab caches that are used for - * 2^x bytes of allocations. - */ -extern struct kmem_cache *kmalloc_caches[SLUB_PAGE_SHIFT]; - -/* - * Sorry that the following has to be that ugly but some versions of GCC - * have trouble with constant propagation and loops. - */ -static __always_inline int kmalloc_index(size_t size) -{ - if (!size) - return 0; - - if (size <= KMALLOC_MIN_SIZE) - return KMALLOC_SHIFT_LOW; - - if (KMALLOC_MIN_SIZE <= 32 && size > 64 && size <= 96) - return 1; - if (KMALLOC_MIN_SIZE <= 64 && size > 128 && size <= 192) - return 2; - if (size <= 8) return 3; - if (size <= 16) return 4; - if (size <= 32) return 5; - if (size <= 64) return 6; - if (size <= 128) return 7; - if (size <= 256) return 8; - if (size <= 512) return 9; - if (size <= 1024) return 10; - if (size <= 2 * 1024) return 11; - if (size <= 4 * 1024) return 12; -/* - * The following is only needed to support architectures with a larger page - * size than 4k. We need to support 2 * PAGE_SIZE here. So for a 64k page - * size we would have to go up to 128k. - */ - if (size <= 8 * 1024) return 13; - if (size <= 16 * 1024) return 14; - if (size <= 32 * 1024) return 15; - if (size <= 64 * 1024) return 16; - if (size <= 128 * 1024) return 17; - if (size <= 256 * 1024) return 18; - if (size <= 512 * 1024) return 19; - if (size <= 1024 * 1024) return 20; - if (size <= 2 * 1024 * 1024) return 21; - BUG(); - return -1; /* Will never be reached */ - -/* - * What we really wanted to do and cannot do because of compiler issues is: - * int i; - * for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) - * if (size <= (1 << i)) - * return i; - */ -} - -/* - * Find the slab cache for a given combination of allocation flags and size. - * - * This ought to end up with a global pointer to the right cache - * in kmalloc_caches. - */ -static __always_inline struct kmem_cache *kmalloc_slab(size_t size) -{ - int index = kmalloc_index(size); - - if (index == 0) - return NULL; - - return kmalloc_caches[index]; -} - -void *kmem_cache_alloc(struct kmem_cache *, gfp_t); -void *__kmalloc(size_t size, gfp_t flags); - -static __always_inline void * -kmalloc_order(size_t size, gfp_t flags, unsigned int order) -{ - void *ret; - - flags |= (__GFP_COMP | __GFP_KMEMCG); - ret = (void *) __get_free_pages(flags, order); - kmemleak_alloc(ret, size, 1, flags); - return ret; -} - -/** - * Calling this on allocated memory will check that the memory - * is expected to be in use, and print warnings if not. - */ -#ifdef CONFIG_SLUB_DEBUG -extern bool verify_mem_not_deleted(const void *x); -#else -static inline bool verify_mem_not_deleted(const void *x) -{ - return true; -} -#endif - -#ifdef CONFIG_TRACING -extern void * -kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size); -extern void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order); -#else -static __always_inline void * -kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size) -{ - return kmem_cache_alloc(s, gfpflags); -} - -static __always_inline void * -kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) -{ - return kmalloc_order(size, flags, order); -} -#endif - -static __always_inline void *kmalloc_large(size_t size, gfp_t flags) -{ - unsigned int order = get_order(size); - return kmalloc_order_trace(size, flags, order); -} - -static __always_inline void *kmalloc(size_t size, gfp_t flags) -{ - if (__builtin_constant_p(size)) { - if (size > SLUB_MAX_SIZE) - return kmalloc_large(size, flags); - - if (!(flags & SLUB_DMA)) { - struct kmem_cache *s = kmalloc_slab(size); - - if (!s) - return ZERO_SIZE_PTR; - - return kmem_cache_alloc_trace(s, flags, size); - } - } - return __kmalloc(size, flags); -} - -#ifdef CONFIG_NUMA -void *__kmalloc_node(size_t size, gfp_t flags, int node); -void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); - -#ifdef CONFIG_TRACING -extern void *kmem_cache_alloc_node_trace(struct kmem_cache *s, - gfp_t gfpflags, - int node, size_t size); -#else -static __always_inline void * -kmem_cache_alloc_node_trace(struct kmem_cache *s, - gfp_t gfpflags, - int node, size_t size) -{ - return kmem_cache_alloc_node(s, gfpflags, node); -} -#endif - -static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) -{ - if (__builtin_constant_p(size) && - size <= SLUB_MAX_SIZE && !(flags & SLUB_DMA)) { - struct kmem_cache *s = kmalloc_slab(size); - - if (!s) - return ZERO_SIZE_PTR; - - return kmem_cache_alloc_node_trace(s, flags, node, size); - } - return __kmalloc_node(size, flags, node); -} -#endif - #endif /* _LINUX_SLUB_DEF_H */ diff --git a/include/linux/smp.h b/include/linux/smp.h index 3e07a7df6478..731f5237d5f4 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -20,7 +20,6 @@ struct call_single_data { smp_call_func_t func; void *info; u16 flags; - u16 priv; }; /* total number of cpus in this system (may exceed NR_CPUS) */ @@ -29,6 +28,27 @@ extern unsigned int total_cpus; int smp_call_function_single(int cpuid, smp_call_func_t func, void *info, int wait); +/* + * Call a function on all processors + */ +int on_each_cpu(smp_call_func_t func, void *info, int wait); + +/* + * Call a function on processors specified by mask, which might include + * the local one. + */ +void on_each_cpu_mask(const struct cpumask *mask, smp_call_func_t func, + void *info, bool wait); + +/* + * Call a function on each processor for which the supplied function + * cond_func returns a positive value. This may include the local + * processor. + */ +void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info), + smp_call_func_t func, void *info, bool wait, + gfp_t gfp_flags); + #ifdef CONFIG_SMP #include <linux/preempt.h> @@ -96,27 +116,6 @@ static inline void call_function_init(void) { } #endif /* - * Call a function on all processors - */ -int on_each_cpu(smp_call_func_t func, void *info, int wait); - -/* - * Call a function on processors specified by mask, which might include - * the local one. - */ -void on_each_cpu_mask(const struct cpumask *mask, smp_call_func_t func, - void *info, bool wait); - -/* - * Call a function on each processor for which the supplied function - * cond_func returns a positive value. This may include the local - * processor. - */ -void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info), - smp_call_func_t func, void *info, bool wait, - gfp_t gfp_flags); - -/* * Mark the boot cpu "online" so that it can call console drivers in * printk() and can access its per-cpu storage. */ @@ -140,42 +139,6 @@ static inline int up_smp_call_function(smp_call_func_t func, void *info) } #define smp_call_function(func, info, wait) \ (up_smp_call_function(func, info)) -#define on_each_cpu(func,info,wait) \ - ({ \ - local_irq_disable(); \ - func(info); \ - local_irq_enable(); \ - 0; \ - }) -/* - * Note we still need to test the mask even for UP - * because we actually can get an empty mask from - * code that on SMP might call us without the local - * CPU in the mask. - */ -#define on_each_cpu_mask(mask, func, info, wait) \ - do { \ - if (cpumask_test_cpu(0, (mask))) { \ - local_irq_disable(); \ - (func)(info); \ - local_irq_enable(); \ - } \ - } while (0) -/* - * Preemption is disabled here to make sure the cond_func is called under the - * same condtions in UP and SMP. - */ -#define on_each_cpu_cond(cond_func, func, info, wait, gfp_flags)\ - do { \ - void *__info = (info); \ - preempt_disable(); \ - if ((cond_func)(0, __info)) { \ - local_irq_disable(); \ - (func)(__info); \ - local_irq_enable(); \ - } \ - preempt_enable(); \ - } while (0) static inline void smp_send_reschedule(int cpu) { } #define smp_prepare_boot_cpu() do {} while (0) @@ -192,6 +155,12 @@ smp_call_function_any(const struct cpumask *mask, smp_call_func_t func, static inline void kick_all_cpus_sync(void) { } +static inline void __smp_call_function_single(int cpuid, + struct call_single_data *data, int wait) +{ + on_each_cpu(data->func, data->info, wait); +} + #endif /* !SMP */ /* diff --git a/include/linux/smpboot.h b/include/linux/smpboot.h index c65dee059913..13e929679550 100644 --- a/include/linux/smpboot.h +++ b/include/linux/smpboot.h @@ -24,6 +24,9 @@ struct smpboot_thread_data; * parked (cpu offline) * @unpark: Optional unpark function, called when the thread is * unparked (cpu online) + * @pre_unpark: Optional unpark function, called before the thread is + * unparked (cpu online). This is not guaranteed to be + * called on the target cpu of the thread. Careful! * @selfparking: Thread is not parked by the park function. * @thread_comm: The base name of the thread */ @@ -37,6 +40,7 @@ struct smp_hotplug_thread { void (*cleanup)(unsigned int cpu, bool online); void (*park)(unsigned int cpu); void (*unpark)(unsigned int cpu); + void (*pre_unpark)(unsigned int cpu); bool selfparking; const char *thread_comm; }; diff --git a/include/linux/smsc911x.h b/include/linux/smsc911x.h index 4dde70e74822..eec3efd19beb 100644 --- a/include/linux/smsc911x.h +++ b/include/linux/smsc911x.h @@ -22,6 +22,7 @@ #define __LINUX_SMSC911X_H__ #include <linux/phy.h> +#include <linux/if_ether.h> /* platform_device configuration data, should be assigned to * the platform_device's dev.platform_data */ @@ -31,7 +32,7 @@ struct smsc911x_platform_config { unsigned int flags; unsigned int shift; phy_interface_t phy_interface; - unsigned char mac[6]; + unsigned char mac[ETH_ALEN]; }; /* Constants for platform_device irq polarity configuration */ diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h index e8d702e0fd89..54f91d35e5fd 100644 --- a/include/linux/sock_diag.h +++ b/include/linux/sock_diag.h @@ -1,6 +1,7 @@ #ifndef __SOCK_DIAG_H__ #define __SOCK_DIAG_H__ +#include <linux/user_namespace.h> #include <uapi/linux/sock_diag.h> struct sk_buff; @@ -22,5 +23,7 @@ int sock_diag_check_cookie(void *sk, __u32 *cookie); void sock_diag_save_cookie(void *sk, __u32 *cookie); int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr); +int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, + struct sk_buff *skb, int attrtype); #endif diff --git a/include/linux/socket.h b/include/linux/socket.h index 2b9f74b0ffea..445ef7519dc2 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -167,6 +167,7 @@ struct ucred { #define AF_PPPOX 24 /* PPPoX sockets */ #define AF_WANPIPE 25 /* Wanpipe API Sockets */ #define AF_LLC 26 /* Linux LLC */ +#define AF_IB 27 /* Native InfiniBand address */ #define AF_CAN 29 /* Controller Area Network */ #define AF_TIPC 30 /* TIPC sockets */ #define AF_BLUETOOTH 31 /* Bluetooth sockets */ @@ -211,6 +212,7 @@ struct ucred { #define PF_PPPOX AF_PPPOX #define PF_WANPIPE AF_WANPIPE #define PF_LLC AF_LLC +#define PF_IB AF_IB #define PF_CAN AF_CAN #define PF_TIPC AF_TIPC #define PF_BLUETOOTH AF_BLUETOOTH @@ -298,22 +300,23 @@ struct ucred { #define SOL_IUCV 277 #define SOL_CAIF 278 #define SOL_ALG 279 +#define SOL_NFC 280 /* IPX options */ #define IPX_TYPE 1 extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred); -extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov, int offset, int len); extern int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset, unsigned int len, __wsum *csump); +extern unsigned long iov_pages(const struct iovec *iov, int offset, + unsigned long nr_segs); extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *address, int mode); -extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, int offset, int len); extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr); @@ -321,6 +324,9 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); struct timespec; +/* The __sys_...msg variants allow MSG_CMSG_COMPAT */ +extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); +extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout); extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, diff --git a/include/linux/spi/at86rf230.h b/include/linux/spi/at86rf230.h index b2b1afbb3202..aa327a8105ad 100644 --- a/include/linux/spi/at86rf230.h +++ b/include/linux/spi/at86rf230.h @@ -26,6 +26,20 @@ struct at86rf230_platform_data { int rstn; int slp_tr; int dig2; + + /* Setting the irq_type will configure the driver to request + * the platform irq trigger type according to the given value + * and configure the interrupt polarity of the device to the + * corresponding polarity. + * + * Allowed values are: IRQF_TRIGGER_RISING, IRQF_TRIGGER_FALLING, + * IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW + * + * Setting it to 0, the driver does not touch the trigger type + * configuration of the interrupt and sets the interrupt polarity + * of the device to high active (the default value). + */ + int irq_type; }; #endif diff --git a/include/linux/spi/mmc_spi.h b/include/linux/spi/mmc_spi.h index 32be8dbdf191..274bc0fa00af 100644 --- a/include/linux/spi/mmc_spi.h +++ b/include/linux/spi/mmc_spi.h @@ -7,6 +7,11 @@ struct device; struct mmc_host; +#define MMC_SPI_USE_CD_GPIO (1 << 0) +#define MMC_SPI_USE_RO_GPIO (1 << 1) +#define MMC_SPI_CD_GPIO_ACTIVE_LOW (1 << 2) +#define MMC_SPI_RO_GPIO_ACTIVE_LOW (1 << 3) + /* Put this in platform_data of a device being used to manage an MMC/SD * card slot. (Modeled after PXA mmc glue; see that for usage examples.) * @@ -21,17 +26,19 @@ struct mmc_spi_platform_data { void *); void (*exit)(struct device *, void *); - /* sense switch on sd cards */ - int (*get_ro)(struct device *); - /* - * If board does not use CD interrupts, driver can optimize polling - * using this function. + * Card Detect and Read Only GPIOs. To enable debouncing on the card + * detect GPIO, set the cd_debounce to the debounce time in + * microseconds. */ - int (*get_cd)(struct device *); + unsigned int flags; + unsigned int cd_gpio; + unsigned int cd_debounce; + unsigned int ro_gpio; /* Capabilities to pass into mmc core (e.g. MMC_CAP_NEEDS_POLL). */ unsigned long caps; + unsigned long caps2; /* how long to debounce card detect, in msecs */ u16 detect_delay; diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h index 61ae1306db23..4835486f58e5 100644 --- a/include/linux/spi/mxs-spi.h +++ b/include/linux/spi/mxs-spi.h @@ -24,7 +24,7 @@ #ifndef __LINUX_SPI_MXS_SPI_H__ #define __LINUX_SPI_MXS_SPI_H__ -#include <linux/fsl/mxs-dma.h> +#include <linux/dmaengine.h> #define ssp_is_old(host) ((host)->devid == IMX23_SSP) @@ -137,9 +137,7 @@ struct mxs_ssp { unsigned int clk_rate; enum mxs_ssp_id devid; - int dma_channel; struct dma_chan *dmach; - struct mxs_dma_data dma_data; unsigned int dma_dir; enum dma_transfer_direction slave_dirn; u32 ssp_pio_words[SSP_PIO_NUM]; diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h index 900f0e328235..a25bd6f65e7f 100644 --- a/include/linux/spi/rspi.h +++ b/include/linux/spi/rspi.h @@ -26,6 +26,8 @@ struct rspi_plat_data { unsigned int dma_rx_id; unsigned dma_width_16bit:1; /* DMAC read/write width = 16-bit */ + + u16 num_chipselect; }; #endif diff --git a/include/linux/spi/spi-tegra.h b/include/linux/spi/spi-tegra.h deleted file mode 100644 index 786932c62edb..000000000000 --- a/include/linux/spi/spi-tegra.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * spi-tegra.h: SPI interface for Nvidia Tegra20 SLINK controller. - * - * Copyright (C) 2011 NVIDIA Corporation - * - * 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. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _LINUX_SPI_TEGRA_H -#define _LINUX_SPI_TEGRA_H - -struct tegra_spi_platform_data { - int dma_req_sel; - unsigned int spi_max_frequency; -}; - -/* - * Controller data from device to pass some info like - * hw based chip select can be used or not and if yes - * then CS hold and setup time. - */ -struct tegra_spi_device_controller_data { - bool is_hw_based_cs; - int cs_setup_clk_count; - int cs_hold_clk_count; -}; - -#endif /* _LINUX_SPI_TEGRA_H */ diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 38c2b925923d..4d634d66ba0b 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -57,7 +57,7 @@ extern struct bus_type spi_bus_type; * @modalias: Name of the driver to use with this device, or an alias * for that name. This appears in the sysfs "modalias" attribute * for driver coldplugging, and in uevents used for hotplugging - * @cs_gpio: gpio number of the chipselect line (optional, -EINVAL when + * @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when * when not using a GPIO line) * * A @spi_device is used to interchange data between an SPI slave @@ -74,7 +74,7 @@ struct spi_device { struct spi_master *master; u32 max_speed_hz; u8 chip_select; - u8 mode; + u16 mode; #define SPI_CPHA 0x01 /* clock phase */ #define SPI_CPOL 0x02 /* clock polarity */ #define SPI_MODE_0 (0|0) /* (original MicroWire) */ @@ -87,6 +87,10 @@ struct spi_device { #define SPI_LOOP 0x20 /* loopback mode */ #define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */ #define SPI_READY 0x80 /* slave pulls low to pause */ +#define SPI_TX_DUAL 0x100 /* transmit with 2 wires */ +#define SPI_TX_QUAD 0x200 /* transmit with 4 wires */ +#define SPI_RX_DUAL 0x400 /* receive with 2 wires */ +#define SPI_RX_QUAD 0x800 /* receive with 4 wires */ u8 bits_per_word; int irq; void *controller_state; @@ -228,6 +232,13 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * every chipselect is connected to a slave. * @dma_alignment: SPI controller constraint on DMA buffers alignment. * @mode_bits: flags understood by this controller driver + * @bits_per_word_mask: A mask indicating which values of bits_per_word are + * supported by the driver. Bit n indicates that a bits_per_word n+1 is + * suported. If set, the SPI core will reject any transfer with an + * unsupported bits_per_word. If not set, this value is simply ignored, + * and it's up to the individual driver to perform any validation. + * @min_speed_hz: Lowest supported transfer speed + * @max_speed_hz: Highest supported transfer speed * @flags: other constraints relevant to this driver * @bus_lock_spinlock: spinlock for SPI bus locking * @bus_lock_mutex: mutex for SPI bus locking @@ -249,6 +260,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @busy: message pump is busy * @running: message pump is running * @rt: whether this queue is set to run as a realtime task + * @auto_runtime_pm: the core should ensure a runtime PM reference is held + * while the hardware is prepared, using the parent + * device for the spidev * @prepare_transfer_hardware: a message will soon arrive from the queue * so the subsystem requests the driver to prepare the transfer hardware * by issuing this call @@ -261,7 +275,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * queue so the subsystem notifies the driver that it may relax the * hardware by issuing this call * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS - * number. Any individual value may be -EINVAL for CS lines that + * number. Any individual value may be -ENOENT for CS lines that * are not GPIOs (driven by the SPI controller itself). * * Each SPI master controller can communicate with one or more @spi_device @@ -301,6 +315,16 @@ struct spi_master { /* spi_device.mode flags understood by this controller driver */ u16 mode_bits; + /* bitmask of supported bits_per_word for transfers */ + u32 bits_per_word_mask; +#define SPI_BPW_MASK(bits) BIT((bits) - 1) +#define SPI_BIT_MASK(bits) (((bits) == 32) ? ~0U : (BIT(bits) - 1)) +#define SPI_BPW_RANGE_MASK(min, max) (SPI_BIT_MASK(max) - SPI_BIT_MASK(min - 1)) + + /* limits on transfer speed */ + u32 min_speed_hz; + u32 max_speed_hz; + /* other constraints relevant to this driver */ u16 flags; #define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */ @@ -363,11 +387,13 @@ struct spi_master { bool busy; bool running; bool rt; + bool auto_runtime_pm; int (*prepare_transfer_hardware)(struct spi_master *master); int (*transfer_one_message)(struct spi_master *master, struct spi_message *mesg); int (*unprepare_transfer_hardware)(struct spi_master *master); + /* gpio chip select */ int *cs_gpios; }; @@ -408,6 +434,8 @@ extern struct spi_master * spi_alloc_master(struct device *host, unsigned size); extern int spi_register_master(struct spi_master *master); +extern int devm_spi_register_master(struct device *dev, + struct spi_master *master); extern void spi_unregister_master(struct spi_master *master); extern struct spi_master *spi_busnum_to_master(u16 busnum); @@ -437,6 +465,10 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); * @rx_buf: data to be read (dma-safe memory), or NULL * @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped * @rx_dma: DMA address of rx_buf, if @spi_message.is_dma_mapped + * @tx_nbits: number of bits used for writting. If 0 the default + * (SPI_NBITS_SINGLE) is used. + * @rx_nbits: number of bits used for reading. If 0 the default + * (SPI_NBITS_SINGLE) is used. * @len: size of rx and tx buffers (in bytes) * @speed_hz: Select a speed other than the device default for this * transfer. If 0 the default (from @spi_device) is used. @@ -491,6 +523,11 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); * by the results of previous messages and where the whole transaction * ends when the chipselect goes intactive. * + * When SPI can transfer in 1x,2x or 4x. It can get this tranfer information + * from device through @tx_nbits and @rx_nbits. In Bi-direction, these + * two should both be set. User can set transfer mode with SPI_NBITS_SINGLE(1x) + * SPI_NBITS_DUAL(2x) and SPI_NBITS_QUAD(4x) to support these three transfer. + * * The code that submits an spi_message (and its spi_transfers) * to the lower layers is responsible for managing its memory. * Zero-initialize every field you don't set up explicitly, to @@ -511,6 +548,11 @@ struct spi_transfer { dma_addr_t rx_dma; unsigned cs_change:1; + u8 tx_nbits; + u8 rx_nbits; +#define SPI_NBITS_SINGLE 0x01 /* 1bit transfer */ +#define SPI_NBITS_DUAL 0x02 /* 2bits transfer */ +#define SPI_NBITS_QUAD 0x04 /* 4bits transfer */ u8 bits_per_word; u16 delay_usecs; u32 speed_hz; @@ -567,6 +609,7 @@ struct spi_message { /* completion is reported through a callback */ void (*complete)(void *context); void *context; + unsigned frame_length; unsigned actual_length; int status; @@ -858,7 +901,7 @@ struct spi_board_info { /* mode becomes spi_device.mode, and is essential for chips * where the default of SPI_CS_HIGH = 0 is wrong. */ - u8 mode; + u16 mode; /* ... may need additional spi_device chip config data here. * avoid stuff protocol drivers can set; but include stuff diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index f987a2bee16a..daebaba886aa 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h @@ -4,11 +4,7 @@ #include <linux/workqueue.h> struct spi_bitbang { - struct workqueue_struct *workqueue; - struct work_struct work; - spinlock_t lock; - struct list_head queue; u8 busy; u8 use_dma; u8 flags; /* extra spi->mode support */ @@ -41,7 +37,6 @@ struct spi_bitbang { */ extern int spi_bitbang_setup(struct spi_device *spi); extern void spi_bitbang_cleanup(struct spi_device *spi); -extern int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m); extern int spi_bitbang_setup_transfer(struct spi_device *spi, struct spi_transfer *t); diff --git a/include/linux/spi/xilinx_spi.h b/include/linux/spi/xilinx_spi.h index 6f17278810b0..333ecdfee0d9 100644 --- a/include/linux/spi/xilinx_spi.h +++ b/include/linux/spi/xilinx_spi.h @@ -11,7 +11,6 @@ */ struct xspi_platform_data { u16 num_chipselect; - bool little_endian; u8 bits_per_word; struct spi_board_info *devices; u8 num_devices; diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 7d537ced949a..75f34949d9ab 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -117,9 +117,17 @@ do { \ #endif /*arch_spin_is_contended*/ #endif -/* The lock does not imply full memory barrier. */ -#ifndef ARCH_HAS_SMP_MB_AFTER_LOCK -static inline void smp_mb__after_lock(void) { smp_mb(); } +/* + * Despite its name it doesn't necessarily has to be a full barrier. + * It should only guarantee that a STORE before the critical section + * can not be reordered with a LOAD inside this section. + * spin_lock() is the one-way barrier, this LOAD can not escape out + * of the region. So the default implementation simply ensures that + * a STORE can not move into the critical section, smp_wmb() should + * serialize it with another STORE done by spin_lock(). + */ +#ifndef smp_mb__before_spinlock +#define smp_mb__before_spinlock() smp_wmb() #endif /** diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h index 51df117abe46..bdb9993f0fda 100644 --- a/include/linux/spinlock_api_smp.h +++ b/include/linux/spinlock_api_smp.h @@ -144,7 +144,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); } -#endif /* CONFIG_PREEMPT */ +#endif /* !CONFIG_GENERIC_LOCKBREAK || CONFIG_DEBUG_LOCK_ALLOC */ static inline void __raw_spin_unlock(raw_spinlock_t *lock) { diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h index a26e2fb604e6..8b3ac0d718eb 100644 --- a/include/linux/spinlock_up.h +++ b/include/linux/spinlock_up.h @@ -16,7 +16,10 @@ * In the debug case, 1 means unlocked, 0 means locked. (the values * are inverted, to catch initialization bugs) * - * No atomicity anywhere, we are on UP. + * No atomicity anywhere, we are on UP. However, we still need + * the compiler barriers, because we do not want the compiler to + * move potentially faulting instructions (notably user accesses) + * into the locked sequence, resulting in non-atomic execution. */ #ifdef CONFIG_DEBUG_SPINLOCK @@ -25,6 +28,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) { lock->slock = 0; + barrier(); } static inline void @@ -32,6 +36,7 @@ arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { local_irq_save(flags); lock->slock = 0; + barrier(); } static inline int arch_spin_trylock(arch_spinlock_t *lock) @@ -39,32 +44,34 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) char oldval = lock->slock; lock->slock = 0; + barrier(); return oldval > 0; } static inline void arch_spin_unlock(arch_spinlock_t *lock) { + barrier(); lock->slock = 1; } /* * Read-write spinlocks. No debug version. */ -#define arch_read_lock(lock) do { (void)(lock); } while (0) -#define arch_write_lock(lock) do { (void)(lock); } while (0) -#define arch_read_trylock(lock) ({ (void)(lock); 1; }) -#define arch_write_trylock(lock) ({ (void)(lock); 1; }) -#define arch_read_unlock(lock) do { (void)(lock); } while (0) -#define arch_write_unlock(lock) do { (void)(lock); } while (0) +#define arch_read_lock(lock) do { barrier(); (void)(lock); } while (0) +#define arch_write_lock(lock) do { barrier(); (void)(lock); } while (0) +#define arch_read_trylock(lock) ({ barrier(); (void)(lock); 1; }) +#define arch_write_trylock(lock) ({ barrier(); (void)(lock); 1; }) +#define arch_read_unlock(lock) do { barrier(); (void)(lock); } while (0) +#define arch_write_unlock(lock) do { barrier(); (void)(lock); } while (0) #else /* DEBUG_SPINLOCK */ #define arch_spin_is_locked(lock) ((void)(lock), 0) -/* for sched.c and kernel_lock.c: */ -# define arch_spin_lock(lock) do { (void)(lock); } while (0) -# define arch_spin_lock_flags(lock, flags) do { (void)(lock); } while (0) -# define arch_spin_unlock(lock) do { (void)(lock); } while (0) -# define arch_spin_trylock(lock) ({ (void)(lock); 1; }) +/* for sched/core.c and kernel_lock.c: */ +# define arch_spin_lock(lock) do { barrier(); (void)(lock); } while (0) +# define arch_spin_lock_flags(lock, flags) do { barrier(); (void)(lock); } while (0) +# define arch_spin_unlock(lock) do { barrier(); (void)(lock); } while (0) +# define arch_spin_trylock(lock) ({ barrier(); (void)(lock); 1; }) #endif /* DEBUG_SPINLOCK */ #define arch_spin_is_contended(lock) (((void)(lock), 0)) diff --git a/include/linux/splice.h b/include/linux/splice.h index 09a545a7dfa3..74575cbf2d6f 100644 --- a/include/linux/splice.h +++ b/include/linux/splice.h @@ -35,6 +35,7 @@ struct splice_desc { void *data; /* cookie */ } u; loff_t pos; /* file position */ + loff_t *opos; /* sendfile: output position */ size_t num_spliced; /* number of bytes already spliced */ bool need_wakeup; /* need to wake up writer */ }; diff --git a/include/linux/srcu.h b/include/linux/srcu.h index 04f4121a23ae..c114614ed172 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -237,47 +237,4 @@ static inline void srcu_read_unlock(struct srcu_struct *sp, int idx) __srcu_read_unlock(sp, idx); } -/** - * srcu_read_lock_raw - register a new reader for an SRCU-protected structure. - * @sp: srcu_struct in which to register the new reader. - * - * Enter an SRCU read-side critical section. Similar to srcu_read_lock(), - * but avoids the RCU-lockdep checking. This means that it is legal to - * use srcu_read_lock_raw() in one context, for example, in an exception - * handler, and then have the matching srcu_read_unlock_raw() in another - * context, for example in the task that took the exception. - * - * However, the entire SRCU read-side critical section must reside within a - * single task. For example, beware of using srcu_read_lock_raw() in - * a device interrupt handler and srcu_read_unlock() in the interrupted - * task: This will not work if interrupts are threaded. - */ -static inline int srcu_read_lock_raw(struct srcu_struct *sp) -{ - unsigned long flags; - int ret; - - local_irq_save(flags); - ret = __srcu_read_lock(sp); - local_irq_restore(flags); - return ret; -} - -/** - * srcu_read_unlock_raw - unregister reader from an SRCU-protected structure. - * @sp: srcu_struct in which to unregister the old reader. - * @idx: return value from corresponding srcu_read_lock_raw(). - * - * Exit an SRCU read-side critical section without lockdep-RCU checking. - * See srcu_read_lock_raw() for more details. - */ -static inline void srcu_read_unlock_raw(struct srcu_struct *sp, int idx) -{ - unsigned long flags; - - local_irq_save(flags); - __srcu_read_unlock(sp, idx); - local_irq_restore(flags); -} - #endif diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 22958d68ecfe..c64999fd1660 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -26,9 +26,9 @@ struct ssb_sprom_core_pwr_info { struct ssb_sprom { u8 revision; - u8 il0mac[6]; /* MAC address for 802.11b/g */ - u8 et0mac[6]; /* MAC address for Ethernet */ - u8 et1mac[6]; /* MAC address for 802.11a */ + u8 il0mac[6] __aligned(sizeof(u16)); /* MAC address for 802.11b/g */ + u8 et0mac[6] __aligned(sizeof(u16)); /* MAC address for Ethernet */ + u8 et1mac[6] __aligned(sizeof(u16)); /* MAC address for 802.11a */ u8 et0phyaddr; /* MII address for enet0 */ u8 et1phyaddr; /* MII address for enet1 */ u8 et0mdcport; /* MDIO for enet0 */ @@ -340,13 +340,61 @@ enum ssb_bustype { #define SSB_BOARDVENDOR_DELL 0x1028 /* Dell */ #define SSB_BOARDVENDOR_HP 0x0E11 /* HP */ /* board_type */ +#define SSB_BOARD_BCM94301CB 0x0406 +#define SSB_BOARD_BCM94301MP 0x0407 +#define SSB_BOARD_BU4309 0x040A +#define SSB_BOARD_BCM94309CB 0x040B +#define SSB_BOARD_BCM4309MP 0x040C +#define SSB_BOARD_BU4306 0x0416 #define SSB_BOARD_BCM94306MP 0x0418 #define SSB_BOARD_BCM4309G 0x0421 #define SSB_BOARD_BCM4306CB 0x0417 -#define SSB_BOARD_BCM4309MP 0x040C +#define SSB_BOARD_BCM94306PC 0x0425 /* pcmcia 3.3v 4306 card */ +#define SSB_BOARD_BCM94306CBSG 0x042B /* with SiGe PA */ +#define SSB_BOARD_PCSG94306 0x042D /* with SiGe PA */ +#define SSB_BOARD_BU4704SD 0x042E /* with sdram */ +#define SSB_BOARD_BCM94704AGR 0x042F /* dual 11a/11g Router */ +#define SSB_BOARD_BCM94308MP 0x0430 /* 11a-only minipci */ +#define SSB_BOARD_BU4318 0x0447 +#define SSB_BOARD_CB4318 0x0448 +#define SSB_BOARD_MPG4318 0x0449 #define SSB_BOARD_MP4318 0x044A -#define SSB_BOARD_BU4306 0x0416 -#define SSB_BOARD_BU4309 0x040A +#define SSB_BOARD_SD4318 0x044B +#define SSB_BOARD_BCM94306P 0x044C /* with SiGe */ +#define SSB_BOARD_BCM94303MP 0x044E +#define SSB_BOARD_BCM94306MPM 0x0450 +#define SSB_BOARD_BCM94306MPL 0x0453 +#define SSB_BOARD_PC4303 0x0454 /* pcmcia */ +#define SSB_BOARD_BCM94306MPLNA 0x0457 +#define SSB_BOARD_BCM94306MPH 0x045B +#define SSB_BOARD_BCM94306PCIV 0x045C +#define SSB_BOARD_BCM94318MPGH 0x0463 +#define SSB_BOARD_BU4311 0x0464 +#define SSB_BOARD_BCM94311MC 0x0465 +#define SSB_BOARD_BCM94311MCAG 0x0466 +/* 4321 boards */ +#define SSB_BOARD_BU4321 0x046B +#define SSB_BOARD_BU4321E 0x047C +#define SSB_BOARD_MP4321 0x046C +#define SSB_BOARD_CB2_4321 0x046D +#define SSB_BOARD_CB2_4321_AG 0x0066 +#define SSB_BOARD_MC4321 0x046E +/* 4325 boards */ +#define SSB_BOARD_BCM94325DEVBU 0x0490 +#define SSB_BOARD_BCM94325BGABU 0x0491 +#define SSB_BOARD_BCM94325SDGWB 0x0492 +#define SSB_BOARD_BCM94325SDGMDL 0x04AA +#define SSB_BOARD_BCM94325SDGMDL2 0x04C6 +#define SSB_BOARD_BCM94325SDGMDL3 0x04C9 +#define SSB_BOARD_BCM94325SDABGWBA 0x04E1 +/* 4322 boards */ +#define SSB_BOARD_BCM94322MC 0x04A4 +#define SSB_BOARD_BCM94322USB 0x04A8 /* dualband */ +#define SSB_BOARD_BCM94322HM 0x04B0 +#define SSB_BOARD_BCM94322USB2D 0x04Bf /* single band discrete front end */ +/* 4312 boards */ +#define SSB_BOARD_BU4312 0x048A +#define SSB_BOARD_BCM4312MCGSG 0x04B5 /* chip_package */ #define SSB_CHIPPACK_BCM4712S 1 /* Small 200pin 4712 */ #define SSB_CHIPPACK_BCM4712M 2 /* Medium 225pin 4712 */ diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index 9e492be5244b..6fcfe99bd999 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h @@ -219,6 +219,7 @@ #define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */ #define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */ #define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16 +#define SSB_CHIPCO_PMU_CTL_PLL_UPD 0x00000400 #define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ #define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ #define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */ @@ -667,5 +668,6 @@ enum ssb_pmu_ldo_volt_id { void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc, enum ssb_pmu_ldo_volt_id id, u32 voltage); void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on); +void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid); #endif /* LINUX_SSB_CHIPCO_H_ */ diff --git a/include/linux/ssb/ssb_driver_mips.h b/include/linux/ssb/ssb_driver_mips.h index afe79d40a99e..6535e4718fde 100644 --- a/include/linux/ssb/ssb_driver_mips.h +++ b/include/linux/ssb/ssb_driver_mips.h @@ -20,6 +20,18 @@ struct ssb_pflash { u32 window_size; }; +#ifdef CONFIG_SSB_SFLASH +struct ssb_sflash { + bool present; + u32 window; + u32 blocksize; + u16 numblocks; + u32 size; + + void *priv; +}; +#endif + struct ssb_mipscore { struct ssb_device *dev; @@ -27,6 +39,9 @@ struct ssb_mipscore { struct ssb_serial_port serial_ports[4]; struct ssb_pflash pflash; +#ifdef CONFIG_SSB_SFLASH + struct ssb_sflash sflash; +#endif }; extern void ssb_mipscore_init(struct ssb_mipscore *mcore); diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index 6ecfa02ddbac..f9f931c89e3e 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -172,6 +172,7 @@ #define SSB_SPROMSIZE_WORDS_R4 220 #define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16)) #define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16)) +#define SSB_SPROMSIZE_WORDS_R10 230 #define SSB_SPROM_BASE1 0x1000 #define SSB_SPROM_BASE31 0x0800 #define SSB_SPROM_REVISION 0x007E @@ -289,11 +290,11 @@ #define SSB_SPROM4_ETHPHY_ET1A_SHIFT 5 #define SSB_SPROM4_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */ #define SSB_SPROM4_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */ -#define SSB_SPROM4_ANTAVAIL 0x005D /* Antenna available bitfields */ -#define SSB_SPROM4_ANTAVAIL_A 0x00FF /* A-PHY bitfield */ -#define SSB_SPROM4_ANTAVAIL_A_SHIFT 0 -#define SSB_SPROM4_ANTAVAIL_BG 0xFF00 /* B-PHY and G-PHY bitfield */ -#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 8 +#define SSB_SPROM4_ANTAVAIL 0x005C /* Antenna available bitfields */ +#define SSB_SPROM4_ANTAVAIL_BG 0x00FF /* B-PHY and G-PHY bitfield */ +#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 0 +#define SSB_SPROM4_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */ +#define SSB_SPROM4_ANTAVAIL_A_SHIFT 8 #define SSB_SPROM4_AGAIN01 0x005E /* Antenna Gain (in dBm Q5.2) */ #define SSB_SPROM4_AGAIN0 0x00FF /* Antenna 0 */ #define SSB_SPROM4_AGAIN0_SHIFT 0 diff --git a/include/linux/ssbi.h b/include/linux/ssbi.h new file mode 100644 index 000000000000..44ef5da21470 --- /dev/null +++ b/include/linux/ssbi.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2010 Google, Inc. + * Copyright (c) 2011, Code Aurora Forum. All rights reserved. + * Author: Dima Zavin <dima@android.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 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _LINUX_SSBI_H +#define _LINUX_SSBI_H + +#include <linux/types.h> + +struct ssbi_slave_info { + const char *name; + void *platform_data; +}; + +enum ssbi_controller_type { + MSM_SBI_CTRL_SSBI = 0, + MSM_SBI_CTRL_SSBI2, + MSM_SBI_CTRL_PMIC_ARBITER, +}; + +struct ssbi_platform_data { + struct ssbi_slave_info slave; + enum ssbi_controller_type controller_type; +}; + +int ssbi_write(struct device *dev, u16 addr, u8 *buf, int len); +int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len); +#endif diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index c1b3ed3fb787..bb5deb0feb6b 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -80,6 +80,10 @@ struct stmmac_mdio_bus_data { unsigned int phy_mask; int *irqs; int probed_phy_irq; +#ifdef CONFIG_OF + int reset_gpio, active_low; + u32 delays[3]; +#endif }; struct stmmac_dma_cfg { @@ -104,6 +108,7 @@ struct plat_stmmacenet_data { int bugged_jumbo; int pmt; int force_sf_dma_mode; + int force_thresh_dma_mode; int riwt_off; void (*fix_mac_speed)(void *priv, unsigned int speed); void (*bus_setup)(void __iomem *ioaddr); diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h index a3eb2f65b656..3eeee9672a4a 100644 --- a/include/linux/string_helpers.h +++ b/include/linux/string_helpers.h @@ -13,4 +13,62 @@ enum string_size_units { int string_get_size(u64 size, enum string_size_units units, char *buf, int len); +#define UNESCAPE_SPACE 0x01 +#define UNESCAPE_OCTAL 0x02 +#define UNESCAPE_HEX 0x04 +#define UNESCAPE_SPECIAL 0x08 +#define UNESCAPE_ANY \ + (UNESCAPE_SPACE | UNESCAPE_OCTAL | UNESCAPE_HEX | UNESCAPE_SPECIAL) + +/** + * string_unescape - unquote characters in the given string + * @src: source buffer (escaped) + * @dst: destination buffer (unescaped) + * @size: size of the destination buffer (0 to unlimit) + * @flags: combination of the flags (bitwise OR): + * %UNESCAPE_SPACE: + * '\f' - form feed + * '\n' - new line + * '\r' - carriage return + * '\t' - horizontal tab + * '\v' - vertical tab + * %UNESCAPE_OCTAL: + * '\NNN' - byte with octal value NNN (1 to 3 digits) + * %UNESCAPE_HEX: + * '\xHH' - byte with hexadecimal value HH (1 to 2 digits) + * %UNESCAPE_SPECIAL: + * '\"' - double quote + * '\\' - backslash + * '\a' - alert (BEL) + * '\e' - escape + * %UNESCAPE_ANY: + * all previous together + * + * Returns amount of characters processed to the destination buffer excluding + * trailing '\0'. + * + * Because the size of the output will be the same as or less than the size of + * the input, the transformation may be performed in place. + * + * Caller must provide valid source and destination pointers. Be aware that + * destination buffer will always be NULL-terminated. Source string must be + * NULL-terminated as well. + */ +int string_unescape(char *src, char *dst, size_t size, unsigned int flags); + +static inline int string_unescape_inplace(char *buf, unsigned int flags) +{ + return string_unescape(buf, buf, 0, flags); +} + +static inline int string_unescape_any(char *src, char *dst, size_t size) +{ + return string_unescape(src, dst, size, UNESCAPE_ANY); +} + +static inline int string_unescape_any_inplace(char *buf) +{ + return string_unescape_any(buf, buf, 0); +} + #endif diff --git a/include/linux/sudmac.h b/include/linux/sudmac.h new file mode 100644 index 000000000000..377b8a5788fa --- /dev/null +++ b/include/linux/sudmac.h @@ -0,0 +1,52 @@ +/* + * Header for the SUDMAC driver + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * This 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 SUDMAC_H +#define SUDMAC_H + +#include <linux/dmaengine.h> +#include <linux/shdma-base.h> +#include <linux/types.h> + +/* Used by slave DMA clients to request DMA to/from a specific peripheral */ +struct sudmac_slave { + struct shdma_slave shdma_slave; /* Set by the platform */ +}; + +/* + * Supplied by platforms to specify, how a DMA channel has to be configured for + * a certain peripheral + */ +struct sudmac_slave_config { + int slave_id; +}; + +struct sudmac_channel { + unsigned long offset; + unsigned long config; + unsigned long wait; /* The configuable range is 0 to 3 */ + unsigned long dint_end_bit; +}; + +struct sudmac_pdata { + const struct sudmac_slave_config *slave; + int slave_num; + const struct sudmac_channel *channel; + int channel_num; +}; + +/* Definitions for the sudmac_channel.config */ +#define SUDMAC_TX_BUFFER_MODE BIT(0) +#define SUDMAC_RX_END_MODE BIT(1) + +/* Definitions for the sudmac_channel.dint_end_bit */ +#define SUDMAC_DMA_BIT_CH0 BIT(0) +#define SUDMAC_DMA_BIT_CH1 BIT(1) + +#endif diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 58fda1c3c783..790be1472792 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -22,12 +22,23 @@ /* size of the nodename buffer */ #define UNX_MAXNODENAME 32 +struct rpcsec_gss_info; + +/* auth_cred ac_flags bits */ +enum { + RPC_CRED_NO_CRKEY_TIMEOUT = 0, /* underlying cred has no key timeout */ + RPC_CRED_KEY_EXPIRE_SOON = 1, /* underlying cred key will expire soon */ + RPC_CRED_NOTIFY_TIMEOUT = 2, /* nofity generic cred when underlying + key will expire soon */ +}; + /* Work around the lack of a VFS credential */ struct auth_cred { kuid_t uid; kgid_t gid; struct group_info *group_info; const char *principal; + unsigned long ac_flags; unsigned char machine_cred : 1; }; @@ -85,6 +96,11 @@ struct rpc_auth { /* per-flavor data */ }; +struct rpc_auth_create_args { + rpc_authflavor_t pseudoflavor; + const char *target_name; +}; + /* Flags for rpcauth_lookupcred() */ #define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */ @@ -95,14 +111,17 @@ struct rpc_authops { struct module *owner; rpc_authflavor_t au_flavor; /* flavor (RPC_AUTH_*) */ char * au_name; - struct rpc_auth * (*create)(struct rpc_clnt *, rpc_authflavor_t); + struct rpc_auth * (*create)(struct rpc_auth_create_args *, struct rpc_clnt *); void (*destroy)(struct rpc_auth *); struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int); struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int); - int (*pipes_create)(struct rpc_auth *); - void (*pipes_destroy)(struct rpc_auth *); int (*list_pseudoflavors)(rpc_authflavor_t *, int); + rpc_authflavor_t (*info2flavor)(struct rpcsec_gss_info *); + int (*flavor2info)(rpc_authflavor_t, + struct rpcsec_gss_info *); + int (*key_timeout)(struct rpc_auth *, + struct rpc_cred *); }; struct rpc_credops { @@ -119,6 +138,8 @@ struct rpc_credops { void *, __be32 *, void *); int (*crunwrap_resp)(struct rpc_task *, kxdrdproc_t, void *, __be32 *, void *); + int (*crkey_timeout)(struct rpc_cred *); + bool (*crkey_to_expire)(struct rpc_cred *); }; extern const struct rpc_authops authunix_ops; @@ -135,8 +156,13 @@ struct rpc_cred * rpc_lookup_cred(void); struct rpc_cred * rpc_lookup_machine_cred(const char *service_name); int rpcauth_register(const struct rpc_authops *); int rpcauth_unregister(const struct rpc_authops *); -struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); +struct rpc_auth * rpcauth_create(struct rpc_auth_create_args *, + struct rpc_clnt *); void rpcauth_release(struct rpc_auth *); +rpc_authflavor_t rpcauth_get_pseudoflavor(rpc_authflavor_t, + struct rpcsec_gss_info *); +int rpcauth_get_gssinfo(rpc_authflavor_t, + struct rpcsec_gss_info *); int rpcauth_list_flavors(rpc_authflavor_t *, int); struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); @@ -153,6 +179,9 @@ int rpcauth_uptodatecred(struct rpc_task *); int rpcauth_init_credcache(struct rpc_auth *); void rpcauth_destroy_credcache(struct rpc_auth *); void rpcauth_clear_credcache(struct rpc_cred_cache *); +int rpcauth_key_timeout_notify(struct rpc_auth *, + struct rpc_cred *); +bool rpcauth_cred_key_to_expire(struct rpc_cred *); static inline struct rpc_cred * get_rpccred(struct rpc_cred *cred) diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h index 303399b1ba59..437ddb6c4aef 100644 --- a/include/linux/sunrpc/cache.h +++ b/include/linux/sunrpc/cache.h @@ -57,6 +57,7 @@ struct cache_head { #define CACHE_VALID 0 /* Entry contains valid data */ #define CACHE_NEGATIVE 1 /* Negative entry - there is no match for the key */ #define CACHE_PENDING 2 /* An upcall has been sent but no reply received yet*/ +#define CACHE_CLEANED 3 /* Entry has been cleaned from cache */ #define CACHE_NEW_EXPIRY 120 /* keep new things pending confirmation for 120 seconds */ @@ -148,6 +149,24 @@ struct cache_deferred_req { int too_many); }; +/* + * timestamps kept in the cache are expressed in seconds + * since boot. This is the best for measuring differences in + * real time. + */ +static inline time_t seconds_since_boot(void) +{ + struct timespec boot; + getboottime(&boot); + return get_seconds() - boot.tv_sec; +} + +static inline time_t convert_to_wallclock(time_t sinceboot) +{ + struct timespec boot; + getboottime(&boot); + return boot.tv_sec + sinceboot; +} extern const struct file_operations cache_file_operations_pipefs; extern const struct file_operations content_file_operations_pipefs; @@ -181,15 +200,10 @@ static inline void cache_put(struct cache_head *h, struct cache_detail *cd) kref_put(&h->ref, cd->cache_put); } -static inline int cache_valid(struct cache_head *h) +static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h) { - /* If an item has been unhashed pending removal when - * the refcount drops to 0, the expiry_time will be - * set to 0. We don't want to consider such items - * valid in this context even though CACHE_VALID is - * set. - */ - return (h->expiry_time != 0 && test_bit(CACHE_VALID, &h->flags)); + return (h->expiry_time < seconds_since_boot()) || + (detail->flush_time > h->last_refresh); } extern int cache_check(struct cache_detail *detail, @@ -250,31 +264,30 @@ static inline int get_uint(char **bpp, unsigned int *anint) return 0; } -/* - * timestamps kept in the cache are expressed in seconds - * since boot. This is the best for measuring differences in - * real time. - */ -static inline time_t seconds_since_boot(void) +static inline int get_time(char **bpp, time_t *time) { - struct timespec boot; - getboottime(&boot); - return get_seconds() - boot.tv_sec; -} + char buf[50]; + long long ll; + int len = qword_get(bpp, buf, sizeof(buf)); -static inline time_t convert_to_wallclock(time_t sinceboot) -{ - struct timespec boot; - getboottime(&boot); - return boot.tv_sec + sinceboot; + if (len < 0) + return -EINVAL; + if (len == 0) + return -ENOENT; + + if (kstrtoll(buf, 0, &ll)) + return -EINVAL; + + *time = (time_t)ll; + return 0; } static inline time_t get_expiry(char **bpp) { - int rv; + time_t rv; struct timespec boot; - if (get_int(bpp, &rv)) + if (get_time(bpp, &rv)) return 0; if (rv < 0) return 0; diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 2cf4ffaa3cd4..6740801aa71a 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -21,6 +21,7 @@ #include <linux/sunrpc/stats.h> #include <linux/sunrpc/xdr.h> #include <linux/sunrpc/timer.h> +#include <linux/sunrpc/rpc_pipe_fs.h> #include <asm/signal.h> #include <linux/path.h> #include <net/ipv6.h> @@ -32,6 +33,7 @@ struct rpc_inode; */ struct rpc_clnt { atomic_t cl_count; /* Number of references */ + unsigned int cl_clid; /* client id */ struct list_head cl_clients; /* Global list of clients */ struct list_head cl_tasks; /* List of tasks */ spinlock_t cl_lock; /* spinlock */ @@ -41,7 +43,6 @@ struct rpc_clnt { cl_vers, /* RPC version number */ cl_maxproc; /* max procedure number */ - const char * cl_protname; /* protocol name */ struct rpc_auth * cl_auth; /* authenticator */ struct rpc_stat * cl_stats; /* per-program statistics */ struct rpc_iostats * cl_metrics; /* per-client statistics */ @@ -56,12 +57,11 @@ struct rpc_clnt { int cl_nodelen; /* nodename length */ char cl_nodename[UNX_MAXNODENAME]; - struct dentry * cl_dentry; + struct rpc_pipe_dir_head cl_pipedir_objects; struct rpc_clnt * cl_parent; /* Points to parent of clones */ struct rpc_rtt cl_rtt_default; struct rpc_timeout cl_timeout_default; const struct rpc_program *cl_program; - char *cl_principal; /* target to authenticate to */ }; /* @@ -124,6 +124,8 @@ struct rpc_create_args { #define RPC_CLNT_CREATE_NOPING (1UL << 4) #define RPC_CLNT_CREATE_DISCRTRY (1UL << 5) #define RPC_CLNT_CREATE_QUIET (1UL << 6) +#define RPC_CLNT_CREATE_INFINITE_SLOTS (1UL << 7) +#define RPC_CLNT_CREATE_NO_IDLE_TIMEOUT (1UL << 8) struct rpc_clnt *rpc_create(struct rpc_create_args *args); struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *, diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h index a19e2547ae6a..1f911ccb2a75 100644 --- a/include/linux/sunrpc/gss_api.h +++ b/include/linux/sunrpc/gss_api.h @@ -25,10 +25,21 @@ struct gss_ctx { #define GSS_C_NO_BUFFER ((struct xdr_netobj) 0) #define GSS_C_NO_CONTEXT ((struct gss_ctx *) 0) -#define GSS_C_NULL_OID ((struct xdr_netobj) 0) +#define GSS_C_QOP_DEFAULT (0) /*XXX arbitrary length - is this set somewhere? */ #define GSS_OID_MAX_LEN 32 +struct rpcsec_gss_oid { + unsigned int len; + u8 data[GSS_OID_MAX_LEN]; +}; + +/* From RFC 3530 */ +struct rpcsec_gss_info { + struct rpcsec_gss_oid oid; + u32 qop; + u32 service; +}; /* gss-api prototypes; note that these are somewhat simplified versions of * the prototypes specified in RFC 2744. */ @@ -37,6 +48,7 @@ int gss_import_sec_context( size_t bufsize, struct gss_api_mech *mech, struct gss_ctx **ctx_id, + time_t *endtime, gfp_t gfp_mask); u32 gss_get_mic( struct gss_ctx *ctx_id, @@ -58,12 +70,14 @@ u32 gss_unwrap( u32 gss_delete_sec_context( struct gss_ctx **ctx_id); -u32 gss_svc_to_pseudoflavor(struct gss_api_mech *, u32 service); +rpc_authflavor_t gss_svc_to_pseudoflavor(struct gss_api_mech *, u32 qop, + u32 service); u32 gss_pseudoflavor_to_service(struct gss_api_mech *, u32 pseudoflavor); char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service); struct pf_desc { u32 pseudoflavor; + u32 qop; u32 service; char *name; char *auth_domain_name; @@ -76,7 +90,7 @@ struct pf_desc { struct gss_api_mech { struct list_head gm_list; struct module *gm_owner; - struct xdr_netobj gm_oid; + struct rpcsec_gss_oid gm_oid; char *gm_name; const struct gss_api_ops *gm_ops; /* pseudoflavors supported by this mechanism: */ @@ -92,6 +106,7 @@ struct gss_api_ops { const void *input_token, size_t bufsize, struct gss_ctx *ctx_id, + time_t *endtime, gfp_t gfp_mask); u32 (*gss_get_mic)( struct gss_ctx *ctx_id, @@ -119,7 +134,13 @@ void gss_mech_unregister(struct gss_api_mech *); /* returns a mechanism descriptor given an OID, and increments the mechanism's * reference count. */ -struct gss_api_mech * gss_mech_get_by_OID(struct xdr_netobj *); +struct gss_api_mech * gss_mech_get_by_OID(struct rpcsec_gss_oid *); + +/* Given a GSS security tuple, look up a pseudoflavor */ +rpc_authflavor_t gss_mech_info2flavor(struct rpcsec_gss_info *); + +/* Given a pseudoflavor, look up a GSS security tuple */ +int gss_mech_flavor2info(rpc_authflavor_t, struct rpcsec_gss_info *); /* Returns a reference to a mechanism, given a name like "krb5" etc. */ struct gss_api_mech *gss_mech_get_by_name(const char *); @@ -130,7 +151,6 @@ struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32); /* Fill in an array with a list of supported pseudoflavors */ int gss_mech_list_pseudoflavors(rpc_authflavor_t *, int); -/* Just increments the mechanism's reference count and returns its input: */ struct gss_api_mech * gss_mech_get(struct gss_api_mech *); /* For every successful gss_mech_get or gss_mech_get_by_* call there must be a diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h index c68a147939a6..aadc6a04e1ac 100644 --- a/include/linux/sunrpc/msg_prot.h +++ b/include/linux/sunrpc/msg_prot.h @@ -138,6 +138,9 @@ typedef __be32 rpc_fraghdr; #define RPC_MAX_HEADER_WITH_AUTH \ (RPC_CALLHDRSIZE + 2*(2+RPC_MAX_AUTH_SIZE/4)) +#define RPC_MAX_REPHEADER_WITH_AUTH \ + (RPC_REPHDRSIZE + (2 + RPC_MAX_AUTH_SIZE/4)) + /* * RFC1833/RFC3530 rpcbind (v3+) well-known netid's. */ diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h index a7b422b33eda..a353e0300b54 100644 --- a/include/linux/sunrpc/rpc_pipe_fs.h +++ b/include/linux/sunrpc/rpc_pipe_fs.h @@ -5,6 +5,26 @@ #include <linux/workqueue.h> +struct rpc_pipe_dir_head { + struct list_head pdh_entries; + struct dentry *pdh_dentry; +}; + +struct rpc_pipe_dir_object_ops; +struct rpc_pipe_dir_object { + struct list_head pdo_head; + const struct rpc_pipe_dir_object_ops *pdo_ops; + + void *pdo_data; +}; + +struct rpc_pipe_dir_object_ops { + int (*create)(struct dentry *dir, + struct rpc_pipe_dir_object *pdo); + void (*destroy)(struct dentry *dir, + struct rpc_pipe_dir_object *pdo); +}; + struct rpc_pipe_msg { struct list_head list; void *data; @@ -73,12 +93,29 @@ extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *, extern int rpc_queue_upcall(struct rpc_pipe *, struct rpc_pipe_msg *); struct rpc_clnt; -extern struct dentry *rpc_create_client_dir(struct dentry *, struct qstr *, struct rpc_clnt *); -extern int rpc_remove_client_dir(struct dentry *); +extern struct dentry *rpc_create_client_dir(struct dentry *, const char *, struct rpc_clnt *); +extern int rpc_remove_client_dir(struct rpc_clnt *); + +extern void rpc_init_pipe_dir_head(struct rpc_pipe_dir_head *pdh); +extern void rpc_init_pipe_dir_object(struct rpc_pipe_dir_object *pdo, + const struct rpc_pipe_dir_object_ops *pdo_ops, + void *pdo_data); +extern int rpc_add_pipe_dir_object(struct net *net, + struct rpc_pipe_dir_head *pdh, + struct rpc_pipe_dir_object *pdo); +extern void rpc_remove_pipe_dir_object(struct net *net, + struct rpc_pipe_dir_head *pdh, + struct rpc_pipe_dir_object *pdo); +extern struct rpc_pipe_dir_object *rpc_find_or_alloc_pipe_dir_object( + struct net *net, + struct rpc_pipe_dir_head *pdh, + int (*match)(struct rpc_pipe_dir_object *, void *), + struct rpc_pipe_dir_object *(*alloc)(void *), + void *data); struct cache_detail; extern struct dentry *rpc_create_cache_dir(struct dentry *, - struct qstr *, + const char *, umode_t umode, struct cache_detail *); extern void rpc_remove_cache_dir(struct dentry *); diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 84ca436b76c2..096ee58be11a 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -79,7 +79,7 @@ struct rpc_task { unsigned short tk_flags; /* misc flags */ unsigned short tk_timeouts; /* maj timeouts */ -#ifdef RPC_DEBUG +#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS) unsigned short tk_pid; /* debugging aid */ #endif unsigned char tk_priority : 2,/* Task priority */ @@ -88,15 +88,6 @@ struct rpc_task { tk_rebind_retry : 2; }; -/* support walking a list of tasks on a wait queue */ -#define task_for_each(task, pos, head) \ - list_for_each(pos, head) \ - if ((task=list_entry(pos, struct rpc_task, u.tk_wait.list)),1) - -#define task_for_first(task, head) \ - if (!list_empty(head) && \ - ((task=list_entry((head)->next, struct rpc_task, u.tk_wait.list)),1)) - typedef void (*rpc_action)(struct rpc_task *); struct rpc_call_ops { @@ -130,6 +121,7 @@ struct rpc_task_setup { #define RPC_TASK_SOFTCONN 0x0400 /* Fail if can't connect */ #define RPC_TASK_SENT 0x0800 /* message was sent */ #define RPC_TASK_TIMEOUT 0x1000 /* fail with ETIMEDOUT on timeout */ +#define RPC_TASK_NOCONNECT 0x2000 /* return ENOTCONN if not connected */ #define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC) #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) @@ -238,7 +230,6 @@ struct rpc_task *rpc_wake_up_first(struct rpc_wait_queue *, bool (*)(struct rpc_task *, void *), void *); void rpc_wake_up_status(struct rpc_wait_queue *, int); -int rpc_queue_empty(struct rpc_wait_queue *); void rpc_delay(struct rpc_task *, unsigned long); void * rpc_malloc(struct rpc_task *, size_t); void rpc_free(void *); @@ -259,16 +250,6 @@ static inline int rpc_wait_for_completion_task(struct rpc_task *task) return __rpc_wait_for_completion_task(task, NULL); } -static inline void rpc_task_set_priority(struct rpc_task *task, unsigned char prio) -{ - task->tk_priority = prio - RPC_PRIORITY_LOW; -} - -static inline int rpc_task_has_priority(struct rpc_task *task, unsigned char prio) -{ - return (task->tk_priority + RPC_PRIORITY_LOW == prio); -} - #if defined(RPC_DEBUG) || defined (RPC_TRACEPOINTS) static inline const char * rpc_qname(const struct rpc_wait_queue *q) { diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 1f0216b9a6c9..6eecfc2e4f98 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -243,7 +243,6 @@ struct svc_rqst { struct xdr_buf rq_res; struct page * rq_pages[RPCSVC_MAXPAGES]; struct page * *rq_respages; /* points into rq_pages */ - int rq_resused; /* number of pages used for result */ struct page * *rq_next_page; /* next reply page to use */ struct kvec rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */ diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h index ff374ab30839..8d71d6577459 100644 --- a/include/linux/sunrpc/svcauth.h +++ b/include/linux/sunrpc/svcauth.h @@ -14,6 +14,7 @@ #include <linux/string.h> #include <linux/sunrpc/msg_prot.h> #include <linux/sunrpc/cache.h> +#include <linux/sunrpc/gss_api.h> #include <linux/hash.h> #include <linux/cred.h> @@ -23,13 +24,23 @@ struct svc_cred { struct group_info *cr_group_info; u32 cr_flavor; /* pseudoflavor */ char *cr_principal; /* for gss */ + struct gss_api_mech *cr_gss_mech; }; +static inline void init_svc_cred(struct svc_cred *cred) +{ + cred->cr_group_info = NULL; + cred->cr_principal = NULL; + cred->cr_gss_mech = NULL; +} + static inline void free_svc_cred(struct svc_cred *cred) { if (cred->cr_group_info) put_group_info(cred->cr_group_info); kfree(cred->cr_principal); + gss_mech_put(cred->cr_gss_mech); + init_svc_cred(cred); } struct svc_rqst; /* forward decl */ diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 30834be03011..cec7b9b5e1bf 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -255,6 +255,9 @@ static inline int bc_prealloc(struct rpc_rqst *req) } #endif /* CONFIG_SUNRPC_BACKCHANNEL */ +#define XPRT_CREATE_INFINITE_SLOTS (1U) +#define XPRT_CREATE_NO_IDLE_TIMEOUT (1U << 1) + struct xprt_create { int ident; /* XPRT_TRANSPORT identifier */ struct net * net; @@ -263,6 +266,7 @@ struct xprt_create { size_t addrlen; const char *servername; struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ + unsigned int flags; }; struct xprt_class { @@ -279,6 +283,7 @@ struct xprt_class { struct rpc_xprt *xprt_create_transport(struct xprt_create *args); void xprt_connect(struct rpc_task *task); void xprt_reserve(struct rpc_task *task); +void xprt_retry_reserve(struct rpc_task *task); int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task); int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task); @@ -334,6 +339,7 @@ int xs_swapper(struct rpc_xprt *xprt, int enable); #define XPRT_CLOSING (6) #define XPRT_CONNECTION_ABORT (7) #define XPRT_CONNECTION_CLOSE (8) +#define XPRT_CONGESTED (9) static inline void xprt_set_connected(struct rpc_xprt *xprt) { diff --git a/include/linux/suspend.h b/include/linux/suspend.h index d4e3f16d5e89..f73cabf59012 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -363,6 +363,7 @@ extern bool pm_wakeup_pending(void); extern bool pm_get_wakeup_count(unsigned int *count, bool block); extern bool pm_save_wakeup_count(unsigned int count); extern void pm_wakep_autosleep_enabled(bool set); +extern void pm_print_active_wakeup_sources(void); static inline void lock_system_sleep(void) { diff --git a/include/linux/swap.h b/include/linux/swap.h index 2818a123f3ea..46ba0c6c219f 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -10,6 +10,7 @@ #include <linux/node.h> #include <linux/fs.h> #include <linux/atomic.h> +#include <linux/page-flags.h> #include <asm/page.h> struct notifier_block; @@ -19,10 +20,13 @@ struct bio; #define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */ #define SWAP_FLAG_PRIO_MASK 0x7fff #define SWAP_FLAG_PRIO_SHIFT 0 -#define SWAP_FLAG_DISCARD 0x10000 /* discard swap cluster after use */ +#define SWAP_FLAG_DISCARD 0x10000 /* enable discard for swap */ +#define SWAP_FLAG_DISCARD_ONCE 0x20000 /* discard swap area at swapon-time */ +#define SWAP_FLAG_DISCARD_PAGES 0x40000 /* discard page-clusters after use */ #define SWAP_FLAGS_VALID (SWAP_FLAG_PRIO_MASK | SWAP_FLAG_PREFER | \ - SWAP_FLAG_DISCARD) + SWAP_FLAG_DISCARD | SWAP_FLAG_DISCARD_ONCE | \ + SWAP_FLAG_DISCARD_PAGES) static inline int current_is_kswapd(void) { @@ -146,14 +150,16 @@ struct swap_extent { enum { SWP_USED = (1 << 0), /* is slot in swap_info[] used? */ SWP_WRITEOK = (1 << 1), /* ok to write to this swap? */ - SWP_DISCARDABLE = (1 << 2), /* swapon+blkdev support discard */ + SWP_DISCARDABLE = (1 << 2), /* blkdev support discard */ SWP_DISCARDING = (1 << 3), /* now discarding a free cluster */ SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */ SWP_CONTINUED = (1 << 5), /* swap_map has count continuation */ SWP_BLKDEV = (1 << 6), /* its a block device */ SWP_FILE = (1 << 7), /* set after swap_activate success */ + SWP_AREA_DISCARD = (1 << 8), /* single-time swap area discards */ + SWP_PAGE_DISCARD = (1 << 9), /* freed swap page-cluster discards */ /* add others here before... */ - SWP_SCANNING = (1 << 8), /* refcount in scan_swap_map */ + SWP_SCANNING = (1 << 10), /* refcount in scan_swap_map */ }; #define SWAP_CLUSTER_MAX 32UL @@ -176,6 +182,33 @@ enum { #define SWAP_MAP_SHMEM 0xbf /* Owned by shmem/tmpfs, in first swap_map */ /* + * We use this to track usage of a cluster. A cluster is a block of swap disk + * space with SWAPFILE_CLUSTER pages long and naturally aligns in disk. All + * free clusters are organized into a list. We fetch an entry from the list to + * get a free cluster. + * + * The data field stores next cluster if the cluster is free or cluster usage + * counter otherwise. The flags field determines if a cluster is free. This is + * protected by swap_info_struct.lock. + */ +struct swap_cluster_info { + unsigned int data:24; + unsigned int flags:8; +}; +#define CLUSTER_FLAG_FREE 1 /* This cluster is free */ +#define CLUSTER_FLAG_NEXT_NULL 2 /* This cluster has no next cluster */ + +/* + * We assign a cluster to each CPU, so each CPU can allocate swap entry from + * its own cluster and swapout sequentially. The purpose is to optimize swapout + * throughput. + */ +struct percpu_cluster { + struct swap_cluster_info index; /* Current cluster index */ + unsigned int next; /* Likely next allocation offset */ +}; + +/* * The in-memory structure used to track swap areas. */ struct swap_info_struct { @@ -185,14 +218,16 @@ struct swap_info_struct { signed char next; /* next type on the swap list */ unsigned int max; /* extent of the swap_map */ unsigned char *swap_map; /* vmalloc'ed array of usage counts */ + struct swap_cluster_info *cluster_info; /* cluster info. Only for SSD */ + struct swap_cluster_info free_cluster_head; /* free cluster list head */ + struct swap_cluster_info free_cluster_tail; /* free cluster list tail */ unsigned int lowest_bit; /* index of first free in swap_map */ unsigned int highest_bit; /* index of last free in swap_map */ unsigned int pages; /* total of usable pages of swap */ unsigned int inuse_pages; /* number of those currently in use */ unsigned int cluster_next; /* likely index for next allocation */ unsigned int cluster_nr; /* countdown to next cluster search */ - unsigned int lowest_alloc; /* while preparing discard cluster */ - unsigned int highest_alloc; /* while preparing discard cluster */ + struct percpu_cluster __percpu *percpu_cluster; /* per cpu's swap location */ struct swap_extent *curr_swap_extent; struct swap_extent first_swap_extent; struct block_device *bdev; /* swap device or bdev of swap file */ @@ -206,14 +241,18 @@ struct swap_info_struct { * protect map scan related fields like * swap_map, lowest_bit, highest_bit, * inuse_pages, cluster_next, - * cluster_nr, lowest_alloc and - * highest_alloc. other fields are only - * changed at swapon/swapoff, so are - * protected by swap_lock. changing - * flags need hold this lock and - * swap_lock. If both locks need hold, - * hold swap_lock first. + * cluster_nr, lowest_alloc, + * highest_alloc, free/discard cluster + * list. other fields are only changed + * at swapon/swapoff, so are protected + * by swap_lock. changing flags need + * hold this lock and swap_lock. If + * both locks need hold, hold swap_lock + * first. */ + struct work_struct discard_work; /* discard worker */ + struct swap_cluster_info discard_cluster_head; /* list head of discard clusters */ + struct swap_cluster_info discard_cluster_tail; /* list tail of discard clusters */ }; struct swap_list_t { @@ -233,15 +272,15 @@ extern unsigned long nr_free_pagecache_pages(void); /* linux/mm/swap.c */ -extern void __lru_cache_add(struct page *, enum lru_list lru); -extern void lru_cache_add_lru(struct page *, enum lru_list lru); +extern void __lru_cache_add(struct page *); +extern void lru_cache_add(struct page *); extern void lru_add_page_tail(struct page *page, struct page *page_tail, - struct lruvec *lruvec); + struct lruvec *lruvec, struct list_head *head); extern void activate_page(struct page *); extern void mark_page_accessed(struct page *); extern void lru_add_drain(void); extern void lru_add_drain_cpu(int cpu); -extern int lru_add_drain_all(void); +extern void lru_add_drain_all(void); extern void rotate_reclaimable_page(struct page *page); extern void deactivate_page(struct page *page); extern void swap_setup(void); @@ -254,12 +293,14 @@ extern void add_page_to_unevictable_list(struct page *page); */ static inline void lru_cache_add_anon(struct page *page) { - __lru_cache_add(page, LRU_INACTIVE_ANON); + ClearPageActive(page); + __lru_cache_add(page); } static inline void lru_cache_add_file(struct page *page) { - __lru_cache_add(page, LRU_INACTIVE_FILE); + ClearPageActive(page); + __lru_cache_add(page); } /* linux/mm/vmscan.c */ @@ -330,6 +371,9 @@ static inline void mem_cgroup_uncharge_swap(swp_entry_t ent) /* linux/mm/page_io.c */ extern int swap_readpage(struct page *); extern int swap_writepage(struct page *page, struct writeback_control *wbc); +extern void end_swap_bio_write(struct bio *bio, int err); +extern int __swap_writepage(struct page *page, struct writeback_control *wbc, + void (*end_write_func)(struct bio *, int)); extern int swap_set_page_dirty(struct page *page); extern void end_swap_bio_read(struct bio *bio, int err); @@ -343,8 +387,9 @@ extern struct address_space swapper_spaces[]; #define swap_address_space(entry) (&swapper_spaces[swp_type(entry)]) extern unsigned long total_swapcache_pages(void); extern void show_swap_cache_info(void); -extern int add_to_swap(struct page *); +extern int add_to_swap(struct page *, struct list_head *list); extern int add_to_swap_cache(struct page *, swp_entry_t, gfp_t); +extern int __add_to_swap_cache(struct page *page, swp_entry_t entry); extern void __delete_from_swap_cache(struct page *); extern void delete_from_swap_cache(struct page *); extern void free_page_and_swap_cache(struct page *); @@ -402,6 +447,7 @@ mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout) #else /* CONFIG_SWAP */ +#define swap_address_space(entry) (NULL) #define get_nr_swap_pages() 0L #define total_swap_pages 0L #define total_swapcache_pages() 0UL @@ -461,7 +507,7 @@ static inline struct page *lookup_swap_cache(swp_entry_t swp) return NULL; } -static inline int add_to_swap(struct page *page) +static inline int add_to_swap(struct page *page, struct list_head *list) { return 0; } diff --git a/include/linux/swapops.h b/include/linux/swapops.h index 47ead515c811..8d4fa82bfb91 100644 --- a/include/linux/swapops.h +++ b/include/linux/swapops.h @@ -67,6 +67,8 @@ static inline swp_entry_t pte_to_swp_entry(pte_t pte) swp_entry_t arch_entry; BUG_ON(pte_file(pte)); + if (pte_swp_soft_dirty(pte)) + pte = pte_swp_clear_soft_dirty(pte); arch_entry = __pte_to_swp_entry(pte); return swp_entry(__swp_type(arch_entry), __swp_offset(arch_entry)); } @@ -137,6 +139,7 @@ static inline void make_migration_entry_read(swp_entry_t *entry) extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, unsigned long address); +extern void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte); #else #define make_migration_entry(page, write) swp_entry(0, 0) @@ -148,6 +151,8 @@ static inline int is_migration_entry(swp_entry_t swp) static inline void make_migration_entry_read(swp_entry_t *entryp) { } static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, unsigned long address) { } +static inline void migration_entry_wait_huge(struct mm_struct *mm, + pte_t *pte) { } static inline int is_write_migration_entry(swp_entry_t entry) { return 0; diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 2de42f9401d2..a5ffd32642fd 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -25,6 +25,7 @@ extern int swiotlb_force; extern void swiotlb_init(int verbose); int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose); extern unsigned long swiotlb_nr_tbl(void); +unsigned long swiotlb_size_or_default(void); extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs); /* diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 313a8e0a6553..7fac04e7ff6e 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -78,49 +78,34 @@ struct sigaltstack; #include <linux/key.h> #include <trace/syscall.h> -#define __SC_DECL1(t1, a1) t1 a1 -#define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__) -#define __SC_DECL3(t3, a3, ...) t3 a3, __SC_DECL2(__VA_ARGS__) -#define __SC_DECL4(t4, a4, ...) t4 a4, __SC_DECL3(__VA_ARGS__) -#define __SC_DECL5(t5, a5, ...) t5 a5, __SC_DECL4(__VA_ARGS__) -#define __SC_DECL6(t6, a6, ...) t6 a6, __SC_DECL5(__VA_ARGS__) - -#define __SC_LONG1(t1, a1) long a1 -#define __SC_LONG2(t2, a2, ...) long a2, __SC_LONG1(__VA_ARGS__) -#define __SC_LONG3(t3, a3, ...) long a3, __SC_LONG2(__VA_ARGS__) -#define __SC_LONG4(t4, a4, ...) long a4, __SC_LONG3(__VA_ARGS__) -#define __SC_LONG5(t5, a5, ...) long a5, __SC_LONG4(__VA_ARGS__) -#define __SC_LONG6(t6, a6, ...) long a6, __SC_LONG5(__VA_ARGS__) - -#define __SC_CAST1(t1, a1) (t1) a1 -#define __SC_CAST2(t2, a2, ...) (t2) a2, __SC_CAST1(__VA_ARGS__) -#define __SC_CAST3(t3, a3, ...) (t3) a3, __SC_CAST2(__VA_ARGS__) -#define __SC_CAST4(t4, a4, ...) (t4) a4, __SC_CAST3(__VA_ARGS__) -#define __SC_CAST5(t5, a5, ...) (t5) a5, __SC_CAST4(__VA_ARGS__) -#define __SC_CAST6(t6, a6, ...) (t6) a6, __SC_CAST5(__VA_ARGS__) - -#define __SC_TEST(type) BUILD_BUG_ON(sizeof(type) > sizeof(long)) -#define __SC_TEST1(t1, a1) __SC_TEST(t1) -#define __SC_TEST2(t2, a2, ...) __SC_TEST(t2); __SC_TEST1(__VA_ARGS__) -#define __SC_TEST3(t3, a3, ...) __SC_TEST(t3); __SC_TEST2(__VA_ARGS__) -#define __SC_TEST4(t4, a4, ...) __SC_TEST(t4); __SC_TEST3(__VA_ARGS__) -#define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) -#define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) +/* + * __MAP - apply a macro to syscall arguments + * __MAP(n, m, t1, a1, t2, a2, ..., tn, an) will expand to + * m(t1, a1), m(t2, a2), ..., m(tn, an) + * The first argument must be equal to the amount of type/name + * pairs given. Note that this list of pairs (i.e. the arguments + * of __MAP starting at the third one) is in the same format as + * for SYSCALL_DEFINE<n>/COMPAT_SYSCALL_DEFINE<n> + */ +#define __MAP0(m,...) +#define __MAP1(m,t,a) m(t,a) +#define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__) +#define __MAP3(m,t,a,...) m(t,a), __MAP2(m,__VA_ARGS__) +#define __MAP4(m,t,a,...) m(t,a), __MAP3(m,__VA_ARGS__) +#define __MAP5(m,t,a,...) m(t,a), __MAP4(m,__VA_ARGS__) +#define __MAP6(m,t,a,...) m(t,a), __MAP5(m,__VA_ARGS__) +#define __MAP(n,...) __MAP##n(__VA_ARGS__) + +#define __SC_DECL(t, a) t a +#define __TYPE_IS_LL(t) (__same_type((t)0, 0LL) || __same_type((t)0, 0ULL)) +#define __SC_LONG(t, a) __typeof(__builtin_choose_expr(__TYPE_IS_LL(t), 0LL, 0L)) a +#define __SC_CAST(t, a) (t) a +#define __SC_ARGS(t, a) a +#define __SC_TEST(t, a) (void)BUILD_BUG_ON_ZERO(!__TYPE_IS_LL(t) && sizeof(t) > sizeof(long)) #ifdef CONFIG_FTRACE_SYSCALLS -#define __SC_STR_ADECL1(t, a) #a -#define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__) -#define __SC_STR_ADECL3(t, a, ...) #a, __SC_STR_ADECL2(__VA_ARGS__) -#define __SC_STR_ADECL4(t, a, ...) #a, __SC_STR_ADECL3(__VA_ARGS__) -#define __SC_STR_ADECL5(t, a, ...) #a, __SC_STR_ADECL4(__VA_ARGS__) -#define __SC_STR_ADECL6(t, a, ...) #a, __SC_STR_ADECL5(__VA_ARGS__) - -#define __SC_STR_TDECL1(t, a) #t -#define __SC_STR_TDECL2(t, a, ...) #t, __SC_STR_TDECL1(__VA_ARGS__) -#define __SC_STR_TDECL3(t, a, ...) #t, __SC_STR_TDECL2(__VA_ARGS__) -#define __SC_STR_TDECL4(t, a, ...) #t, __SC_STR_TDECL3(__VA_ARGS__) -#define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) -#define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) +#define __SC_STR_ADECL(t, a) #a +#define __SC_STR_TDECL(t, a) #t extern struct ftrace_event_class event_class_syscall_enter; extern struct ftrace_event_class event_class_syscall_exit; @@ -155,7 +140,13 @@ extern struct trace_event_functions exit_syscall_print_funcs; __attribute__((section("_ftrace_events"))) \ *__event_exit_##sname = &event_exit_##sname; -#define SYSCALL_METADATA(sname, nb) \ +#define SYSCALL_METADATA(sname, nb, ...) \ + static const char *types_##sname[] = { \ + __MAP(nb,__SC_STR_TDECL,__VA_ARGS__) \ + }; \ + static const char *args_##sname[] = { \ + __MAP(nb,__SC_STR_ADECL,__VA_ARGS__) \ + }; \ SYSCALL_TRACE_ENTER_EVENT(sname); \ SYSCALL_TRACE_EXIT_EVENT(sname); \ static struct syscall_metadata __used \ @@ -163,8 +154,8 @@ extern struct trace_event_functions exit_syscall_print_funcs; .name = "sys"#sname, \ .syscall_nr = -1, /* Filled in at boot */ \ .nb_args = nb, \ - .types = types_##sname, \ - .args = args_##sname, \ + .types = nb ? types_##sname : NULL, \ + .args = nb ? args_##sname : NULL, \ .enter_event = &event_enter_##sname, \ .exit_event = &event_exit_##sname, \ .enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \ @@ -172,26 +163,13 @@ extern struct trace_event_functions exit_syscall_print_funcs; static struct syscall_metadata __used \ __attribute__((section("__syscalls_metadata"))) \ *__p_syscall_meta_##sname = &__syscall_meta_##sname; +#else +#define SYSCALL_METADATA(sname, nb, ...) +#endif #define SYSCALL_DEFINE0(sname) \ - SYSCALL_TRACE_ENTER_EVENT(_##sname); \ - SYSCALL_TRACE_EXIT_EVENT(_##sname); \ - static struct syscall_metadata __used \ - __syscall_meta__##sname = { \ - .name = "sys_"#sname, \ - .syscall_nr = -1, /* Filled in at boot */ \ - .nb_args = 0, \ - .enter_event = &event_enter__##sname, \ - .exit_event = &event_exit__##sname, \ - .enter_fields = LIST_HEAD_INIT(__syscall_meta__##sname.enter_fields), \ - }; \ - static struct syscall_metadata __used \ - __attribute__((section("__syscalls_metadata"))) \ - *__p_syscall_meta_##sname = &__syscall_meta__##sname; \ + SYSCALL_METADATA(_##sname, 0); \ asmlinkage long sys_##sname(void) -#else -#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) -#endif #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) @@ -200,57 +178,24 @@ extern struct trace_event_functions exit_syscall_print_funcs; #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) -#ifdef CONFIG_PPC64 -#define SYSCALL_ALIAS(alias, name) \ - asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ - "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) -#else -#if defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) -#define SYSCALL_ALIAS(alias, name) \ - asm ( #alias " = " #name "\n\t.globl " #alias) -#else -#define SYSCALL_ALIAS(alias, name) \ - asm ("\t.globl " #alias "\n\t.set " #alias ", " #name) -#endif -#endif - -#ifdef CONFIG_FTRACE_SYSCALLS -#define SYSCALL_DEFINEx(x, sname, ...) \ - static const char *types_##sname[] = { \ - __SC_STR_TDECL##x(__VA_ARGS__) \ - }; \ - static const char *args_##sname[] = { \ - __SC_STR_ADECL##x(__VA_ARGS__) \ - }; \ - SYSCALL_METADATA(sname, x); \ - __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) -#else #define SYSCALL_DEFINEx(x, sname, ...) \ + SYSCALL_METADATA(sname, x, __VA_ARGS__) \ __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) -#endif - -#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS - -#define SYSCALL_DEFINE(name) static inline long SYSC_##name +#define __PROTECT(...) asmlinkage_protect(__VA_ARGS__) #define __SYSCALL_DEFINEx(x, name, ...) \ - asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \ - static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \ - asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \ + asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ + static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ + asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ + asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ { \ - __SC_TEST##x(__VA_ARGS__); \ - return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__)); \ + long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \ + __MAP(x,__SC_TEST,__VA_ARGS__); \ + __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ + return ret; \ } \ SYSCALL_ALIAS(sys##name, SyS##name); \ - static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)) - -#else /* CONFIG_HAVE_SYSCALL_WRAPPERS */ - -#define SYSCALL_DEFINE(name) asmlinkage long sys_##name -#define __SYSCALL_DEFINEx(x, name, ...) \ - asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)) - -#endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ + static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)) asmlinkage long sys_time(time_t __user *tloc); asmlinkage long sys_stime(time_t __user *tptr); @@ -694,7 +639,7 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); asmlinkage long sys_semget(key_t key, int nsems, int semflg); asmlinkage long sys_semop(int semid, struct sembuf __user *sops, unsigned nsops); -asmlinkage long sys_semctl(int semid, int semnum, int cmd, union semun arg); +asmlinkage long sys_semctl(int semid, int semnum, int cmd, unsigned long arg); asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops, unsigned nsops, const struct timespec __user *timeout); @@ -858,9 +803,14 @@ asmlinkage long sys_vfork(void); asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, int, int __user *); #else +#ifdef CONFIG_CLONE_BACKWARDS3 +asmlinkage long sys_clone(unsigned long, unsigned long, int, int __user *, + int __user *, int); +#else asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, int __user *, int); #endif +#endif asmlinkage long sys_execve(const char __user *filename, const char __user *const __user *argv, diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index e2cee22f578a..6695040a0317 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -17,10 +17,12 @@ #include <linux/list.h> #include <linux/lockdep.h> #include <linux/kobject_ns.h> +#include <linux/stat.h> #include <linux/atomic.h> struct kobject; struct module; +struct bin_attribute; enum kobj_ns_type; struct attribute { @@ -49,9 +51,9 @@ do { \ static struct lock_class_key __key; \ \ (attr)->key = &__key; \ -} while(0) +} while (0) #else -#define sysfs_attr_init(attr) do {} while(0) +#define sysfs_attr_init(attr) do {} while (0) #endif struct attribute_group { @@ -59,26 +61,33 @@ struct attribute_group { umode_t (*is_visible)(struct kobject *, struct attribute *, int); struct attribute **attrs; + struct bin_attribute **bin_attrs; }; - - /** * Use these macros to make defining attributes easier. See include/linux/device.h * for examples.. */ -#define __ATTR(_name,_mode,_show,_store) { \ - .attr = {.name = __stringify(_name), .mode = _mode }, \ - .show = _show, \ - .store = _store, \ +#define __ATTR(_name, _mode, _show, _store) { \ + .attr = {.name = __stringify(_name), .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +} + +#define __ATTR_RO(_name) { \ + .attr = { .name = __stringify(_name), .mode = S_IRUGO }, \ + .show = _name##_show, \ } -#define __ATTR_RO(_name) { \ - .attr = { .name = __stringify(_name), .mode = 0444 }, \ - .show = _name##_show, \ +#define __ATTR_WO(_name) { \ + .attr = { .name = __stringify(_name), .mode = S_IWUSR }, \ + .store = _name##_store, \ } +#define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \ + _name##_show, _name##_store) + #define __ATTR_NULL { .attr = { .name = NULL } } #ifdef CONFIG_DEBUG_LOCK_ALLOC @@ -92,7 +101,17 @@ struct attribute_group { #define __ATTR_IGNORE_LOCKDEP __ATTR #endif -#define attr_name(_attr) (_attr).attr.name +#define __ATTRIBUTE_GROUPS(_name) \ +static const struct attribute_group *_name##_groups[] = { \ + &_name##_group, \ + NULL, \ +} + +#define ATTRIBUTE_GROUPS(_name) \ +static const struct attribute_group _name##_group = { \ + .attrs = _name##_attrs, \ +}; \ +__ATTRIBUTE_GROUPS(_name) struct file; struct vm_area_struct; @@ -103,7 +122,7 @@ struct bin_attribute { void *private; ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *, char *, loff_t, size_t); - ssize_t (*write)(struct file *,struct kobject *, struct bin_attribute *, + ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *, char *, loff_t, size_t); int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr, struct vm_area_struct *vma); @@ -121,10 +140,39 @@ struct bin_attribute { */ #define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr) +/* macros to create static binary attributes easier */ +#define __BIN_ATTR(_name, _mode, _read, _write, _size) { \ + .attr = { .name = __stringify(_name), .mode = _mode }, \ + .read = _read, \ + .write = _write, \ + .size = _size, \ +} + +#define __BIN_ATTR_RO(_name, _size) { \ + .attr = { .name = __stringify(_name), .mode = S_IRUGO }, \ + .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_NULL __ATTR_NULL + +#define BIN_ATTR(_name, _mode, _read, _write, _size) \ +struct bin_attribute bin_attr_##_name = __BIN_ATTR(_name, _mode, _read, \ + _write, _size) + +#define BIN_ATTR_RO(_name, _size) \ +struct bin_attribute bin_attr_##_name = __BIN_ATTR_RO(_name, _size) + +#define BIN_ATTR_RW(_name, _size) \ +struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size) + struct sysfs_ops { - ssize_t (*show)(struct kobject *, struct attribute *,char *); - ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); - const void *(*namespace)(struct kobject *, const struct attribute *); + ssize_t (*show)(struct kobject *, struct attribute *, char *); + ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t); }; struct sysfs_dirent; @@ -134,19 +182,23 @@ struct sysfs_dirent; int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), void *data, struct module *owner); -int __must_check sysfs_create_dir(struct kobject *kobj); +int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns); void sysfs_remove_dir(struct kobject *kobj); -int __must_check sysfs_rename_dir(struct kobject *kobj, const char *new_name); -int __must_check sysfs_move_dir(struct kobject *kobj, - struct kobject *new_parent_kobj); - -int __must_check sysfs_create_file(struct kobject *kobj, - const struct attribute *attr); +int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name, + const void *new_ns); +int __must_check sysfs_move_dir_ns(struct kobject *kobj, + struct kobject *new_parent_kobj, + const void *new_ns); + +int __must_check sysfs_create_file_ns(struct kobject *kobj, + const struct attribute *attr, + const void *ns); int __must_check sysfs_create_files(struct kobject *kobj, const struct attribute **attr); int __must_check sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr, umode_t mode); -void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr); +void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr, + const void *ns); void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr); int __must_check sysfs_create_bin_file(struct kobject *kobj, @@ -161,18 +213,23 @@ int __must_check sysfs_create_link_nowarn(struct kobject *kobj, const char *name); void sysfs_remove_link(struct kobject *kobj, const char *name); -int sysfs_rename_link(struct kobject *kobj, struct kobject *target, - const char *old_name, const char *new_name); +int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *target, + const char *old_name, const char *new_name, + const void *new_ns); void sysfs_delete_link(struct kobject *dir, struct kobject *targ, const char *name); int __must_check sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp); +int __must_check sysfs_create_groups(struct kobject *kobj, + const struct attribute_group **groups); int sysfs_update_group(struct kobject *kobj, const struct attribute_group *grp); void sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp); +void sysfs_remove_groups(struct kobject *kobj, + const struct attribute_group **groups); int sysfs_add_file_to_group(struct kobject *kobj, const struct attribute *attr, const char *group); void sysfs_remove_file_from_group(struct kobject *kobj, @@ -188,9 +245,9 @@ void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name, void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr); void sysfs_notify_dirent(struct sysfs_dirent *sd); -struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, - const void *ns, - const unsigned char *name); +struct sysfs_dirent *sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd, + const unsigned char *name, + const void *ns); struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd); void sysfs_put(struct sysfs_dirent *sd); @@ -204,7 +261,7 @@ static inline int sysfs_schedule_callback(struct kobject *kobj, return -ENOSYS; } -static inline int sysfs_create_dir(struct kobject *kobj) +static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns) { return 0; } @@ -213,19 +270,22 @@ static inline void sysfs_remove_dir(struct kobject *kobj) { } -static inline int sysfs_rename_dir(struct kobject *kobj, const char *new_name) +static inline int sysfs_rename_dir_ns(struct kobject *kobj, + const char *new_name, const void *new_ns) { return 0; } -static inline int sysfs_move_dir(struct kobject *kobj, - struct kobject *new_parent_kobj) +static inline int sysfs_move_dir_ns(struct kobject *kobj, + struct kobject *new_parent_kobj, + const void *new_ns) { return 0; } -static inline int sysfs_create_file(struct kobject *kobj, - const struct attribute *attr) +static inline int sysfs_create_file_ns(struct kobject *kobj, + const struct attribute *attr, + const void *ns) { return 0; } @@ -242,8 +302,9 @@ static inline int sysfs_chmod_file(struct kobject *kobj, return 0; } -static inline void sysfs_remove_file(struct kobject *kobj, - const struct attribute *attr) +static inline void sysfs_remove_file_ns(struct kobject *kobj, + const struct attribute *attr, + const void *ns) { } @@ -280,8 +341,9 @@ static inline void sysfs_remove_link(struct kobject *kobj, const char *name) { } -static inline int sysfs_rename_link(struct kobject *k, struct kobject *t, - const char *old_name, const char *new_name) +static inline int sysfs_rename_link_ns(struct kobject *k, struct kobject *t, + const char *old_name, + const char *new_name, const void *ns) { return 0; } @@ -297,6 +359,12 @@ static inline int sysfs_create_group(struct kobject *kobj, return 0; } +static inline int sysfs_create_groups(struct kobject *kobj, + const struct attribute_group **groups) +{ + return 0; +} + static inline int sysfs_update_group(struct kobject *kobj, const struct attribute_group *grp) { @@ -308,6 +376,11 @@ static inline void sysfs_remove_group(struct kobject *kobj, { } +static inline void sysfs_remove_groups(struct kobject *kobj, + const struct attribute_group **groups) +{ +} + static inline int sysfs_add_file_to_group(struct kobject *kobj, const struct attribute *attr, const char *group) { @@ -349,10 +422,9 @@ static inline void sysfs_notify(struct kobject *kobj, const char *dir, static inline void sysfs_notify_dirent(struct sysfs_dirent *sd) { } -static inline -struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, - const void *ns, - const unsigned char *name) +static inline struct sysfs_dirent * +sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd, const unsigned char *name, + const void *ns) { return NULL; } @@ -371,4 +443,28 @@ static inline int __must_check sysfs_init(void) #endif /* CONFIG_SYSFS */ +static inline int __must_check sysfs_create_file(struct kobject *kobj, + const struct attribute *attr) +{ + return sysfs_create_file_ns(kobj, attr, NULL); +} + +static inline void sysfs_remove_file(struct kobject *kobj, + const struct attribute *attr) +{ + return sysfs_remove_file_ns(kobj, attr, NULL); +} + +static inline int sysfs_rename_link(struct kobject *kobj, struct kobject *target, + const char *old_name, const char *new_name) +{ + return sysfs_rename_link_ns(kobj, target, old_name, new_name, NULL); +} + +static inline struct sysfs_dirent * +sysfs_get_dirent(struct sysfs_dirent *parent_sd, const unsigned char *name) +{ + return sysfs_get_dirent_ns(parent_sd, name, NULL); +} + #endif /* _SYSFS_H_ */ diff --git a/include/linux/syslog.h b/include/linux/syslog.h index 38911391a139..98a3153c0f96 100644 --- a/include/linux/syslog.h +++ b/include/linux/syslog.h @@ -44,8 +44,8 @@ /* Return size of the log buffer */ #define SYSLOG_ACTION_SIZE_BUFFER 10 -#define SYSLOG_FROM_CALL 0 -#define SYSLOG_FROM_FILE 1 +#define SYSLOG_FROM_READER 0 +#define SYSLOG_FROM_PROC 1 int do_syslog(int type, char __user *buf, int count, bool from_file); diff --git a/include/linux/tcp.h b/include/linux/tcp.h index f28408c07dc2..d68633452d9b 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -90,9 +90,6 @@ struct tcp_options_received { sack_ok : 4, /* SACK seen on SYN packet */ snd_wscale : 4, /* Window scaling received from sender */ rcv_wscale : 4; /* Window scaling to send to receiver */ - u8 cookie_plus:6, /* bytes in authenticator/cookie option */ - cookie_out_never:1, - cookie_in_always:1; u8 num_sacks; /* Number of SACK blocks */ u16 user_mss; /* mss requested by user in ioctl */ u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ @@ -102,7 +99,6 @@ static inline void tcp_clear_options(struct tcp_options_received *rx_opt) { rx_opt->tstamp_ok = rx_opt->sack_ok = 0; rx_opt->wscale_ok = rx_opt->snd_wscale = 0; - rx_opt->cookie_plus = 0; } /* This is the max number of SACKS that we'll generate and process. It's safe @@ -111,7 +107,6 @@ static inline void tcp_clear_options(struct tcp_options_received *rx_opt) * only four options will fit in a standard TCP header */ #define TCP_NUM_SACKS 4 -struct tcp_cookie_values; struct tcp_request_sock_ops; struct tcp_request_sock { @@ -191,20 +186,19 @@ struct tcp_sock { u32 window_clamp; /* Maximal window to advertise */ u32 rcv_ssthresh; /* Current window clamp */ - u32 frto_highmark; /* snd_nxt when RTO occurred */ u16 advmss; /* Advertised MSS */ - u8 frto_counter; /* Number of new acks after RTO */ + u8 unused; u8 nonagle : 4,/* Disable Nagle algorithm? */ thin_lto : 1,/* Use linear timeouts for thin streams */ thin_dupack : 1,/* Fast retransmit on first dupack */ repair : 1, - unused : 1; + frto : 1;/* F-RTO (RFC5682) activated in CA_Loss */ u8 repair_queue; u8 do_early_retrans:1,/* Enable RFC5827 early-retransmit */ - early_retrans_delayed:1, /* Delayed ER timer installed */ syn_data:1, /* SYN includes data */ syn_fastopen:1, /* SYN includes Fast Open option */ syn_data_acked:1;/* data in SYN is acked by SYN-ACK */ + u32 tlp_high_seq; /* snd_nxt at the time of TLP retransmit. */ /* RTT measurement */ u32 srtt; /* smoothed round trip time << 3 */ @@ -243,6 +237,7 @@ struct tcp_sock { u32 rcv_wnd; /* Current receiver window */ u32 write_seq; /* Tail(+1) of data held in tcp send buffer */ + u32 notsent_lowat; /* TCP_NOTSENT_LOWAT */ u32 pushed_seq; /* Last pushed seq, required to talk to windows */ u32 lost_out; /* Lost packets */ u32 sacked_out; /* SACK'd packets */ @@ -251,7 +246,6 @@ struct tcp_sock { /* from STCP, retrans queue hinting */ struct sk_buff* lost_skb_hint; - struct sk_buff *scoreboard_skb_hint; struct sk_buff *retransmit_skb_hint; struct sk_buff_head out_of_order_queue; /* Out of order segments go here */ @@ -320,12 +314,6 @@ struct tcp_sock { struct tcp_md5sig_info __rcu *md5sig_info; #endif - /* When the cookie options are generated and exchanged, then this - * object holds a reference to them (cookie_values->kref). Also - * contains related tcp_cookie_transactions fields. - */ - struct tcp_cookie_values *cookie_values; - /* TCP fastopen related information */ struct tcp_fastopen_request *fastopen_req; /* fastopen_rsk points to request_sock that resulted in this big @@ -361,10 +349,6 @@ struct tcp_timewait_sock { #ifdef CONFIG_TCP_MD5SIG struct tcp_md5sig_key *tw_md5_key; #endif - /* Few sockets in timewait have cookies; in that case, then this - * object holds a reference to them (tw_cookie_values->kref). - */ - struct tcp_cookie_values *tw_cookie_values; }; static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) diff --git a/include/linux/tegra-cpuidle.h b/include/linux/tegra-cpuidle.h new file mode 100644 index 000000000000..9c6286bbf662 --- /dev/null +++ b/include/linux/tegra-cpuidle.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __LINUX_TEGRA_CPUIDLE_H__ +#define __LINUX_TEGRA_CPUIDLE_H__ + +#ifdef CONFIG_CPU_IDLE +void tegra_cpuidle_pcie_irqs_in_use(void); +#else +static inline void tegra_cpuidle_pcie_irqs_in_use(void) +{ +} +#endif + +#endif diff --git a/include/linux/tegra-powergate.h b/include/linux/tegra-powergate.h new file mode 100644 index 000000000000..55c29a8d5015 --- /dev/null +++ b/include/linux/tegra-powergate.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010 Google, Inc + * + * Author: + * Colin Cross <ccross@google.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _MACH_TEGRA_POWERGATE_H_ +#define _MACH_TEGRA_POWERGATE_H_ + +struct clk; + +#define TEGRA_POWERGATE_CPU 0 +#define TEGRA_POWERGATE_3D 1 +#define TEGRA_POWERGATE_VENC 2 +#define TEGRA_POWERGATE_PCIE 3 +#define TEGRA_POWERGATE_VDEC 4 +#define TEGRA_POWERGATE_L2 5 +#define TEGRA_POWERGATE_MPE 6 +#define TEGRA_POWERGATE_HEG 7 +#define TEGRA_POWERGATE_SATA 8 +#define TEGRA_POWERGATE_CPU1 9 +#define TEGRA_POWERGATE_CPU2 10 +#define TEGRA_POWERGATE_CPU3 11 +#define TEGRA_POWERGATE_CELP 12 +#define TEGRA_POWERGATE_3D1 13 + +#define TEGRA_POWERGATE_CPU0 TEGRA_POWERGATE_CPU +#define TEGRA_POWERGATE_3D0 TEGRA_POWERGATE_3D + +int tegra_powergate_is_powered(int id); +int tegra_powergate_power_on(int id); +int tegra_powergate_power_off(int id); +int tegra_powergate_remove_clamping(int id); + +/* Must be called with clk disabled, and returns with clk enabled */ +int tegra_powergate_sequence_power_up(int id, struct clk *clk); + +#endif /* _MACH_TEGRA_POWERGATE_H_ */ diff --git a/include/linux/thermal.h b/include/linux/thermal.h index f0bd7f90a90d..b268d3cf7ae3 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -33,8 +33,11 @@ #define THERMAL_MAX_TRIPS 12 #define THERMAL_NAME_LENGTH 20 +/* invalid cooling state */ +#define THERMAL_CSTATE_INVALID -1UL + /* No upper/lower limit requirement */ -#define THERMAL_NO_LIMIT -1UL +#define THERMAL_NO_LIMIT THERMAL_CSTATE_INVALID /* Unit conversion macros */ #define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \ @@ -44,7 +47,7 @@ /* Adding event notification support elements */ #define THERMAL_GENL_FAMILY_NAME "thermal_event" #define THERMAL_GENL_VERSION 0x01 -#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_group" +#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_grp" /* Default Thermal Governor */ #if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE) @@ -184,7 +187,6 @@ struct thermal_governor { char name[THERMAL_NAME_LENGTH]; int (*throttle)(struct thermal_zone_device *tz, int trip); struct list_head governor_list; - struct module *owner; }; /* Structure that holds binding parameters for a zone */ @@ -205,6 +207,16 @@ struct thermal_bind_params { * See Documentation/thermal/sysfs-api.txt for more information. */ int trip_mask; + + /* + * This is an array of cooling state limits. Must have exactly + * 2 * thermal_zone.number_of_trip_points. It is an array consisting + * of tuples <lower-state upper-state> of state limits. Each trip + * will be associated with one state limit tuple when binding. + * A NULL pointer means <THERMAL_NO_LIMITS THERMAL_NO_LIMITS> + * on all trips. + */ + unsigned long *binding_limits; int (*match) (struct thermal_zone_device *tz, struct thermal_cooling_device *cdev); }; @@ -212,6 +224,14 @@ struct thermal_bind_params { /* Structure to define Thermal Zone parameters */ struct thermal_zone_params { char governor_name[THERMAL_NAME_LENGTH]; + + /* + * a boolean to indicate if the thermal to hwmon sysfs interface + * is required. when no_hwmon == false, a hwmon sysfs interface + * will be created. when no_hwmon == true, nothing will be done + */ + bool no_hwmon; + int num_tbps; /* Number of tbp entries */ struct thermal_bind_params *tbp; }; @@ -237,21 +257,20 @@ void thermal_zone_device_update(struct thermal_zone_device *); struct thermal_cooling_device *thermal_cooling_device_register(char *, void *, const struct thermal_cooling_device_ops *); void thermal_cooling_device_unregister(struct thermal_cooling_device *); +struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name); +int thermal_zone_get_temp(struct thermal_zone_device *tz, unsigned long *temp); int get_tz_trend(struct thermal_zone_device *, int); struct thermal_instance *get_thermal_instance(struct thermal_zone_device *, struct thermal_cooling_device *, int); void thermal_cdev_update(struct thermal_cooling_device *); -void notify_thermal_framework(struct thermal_zone_device *, int); - -int thermal_register_governor(struct thermal_governor *); -void thermal_unregister_governor(struct thermal_governor *); +void thermal_notify_framework(struct thermal_zone_device *, int); #ifdef CONFIG_NET extern int thermal_generate_netlink_event(struct thermal_zone_device *tz, enum events event); #else -static int thermal_generate_netlink_event(struct thermal_zone_device *tz, +static inline int thermal_generate_netlink_event(struct thermal_zone_device *tz, enum events event) { return 0; diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index e7e04736802f..fddbe2023a5d 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -104,8 +104,21 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag) #define test_thread_flag(flag) \ test_ti_thread_flag(current_thread_info(), flag) -#define set_need_resched() set_thread_flag(TIF_NEED_RESCHED) -#define clear_need_resched() clear_thread_flag(TIF_NEED_RESCHED) +static inline __deprecated void set_need_resched(void) +{ + /* + * Use of this function in deprecated. + * + * As of this writing there are only a few users in the DRM tree left + * all of which are wrong and can be removed without causing too much + * grief. + * + * The DRM people are aware and are working on removing the last few + * instances. + */ +} + +#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED) #if defined TIF_RESTORE_SIGMASK && !defined HAVE_SET_RESTORE_SIGMASK /* diff --git a/include/linux/tick.h b/include/linux/tick.h index 553272e6af55..5128d33bbb39 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -10,6 +10,8 @@ #include <linux/irqflags.h> #include <linux/percpu.h> #include <linux/hrtimer.h> +#include <linux/context_tracking_state.h> +#include <linux/cpumask.h> #ifdef CONFIG_GENERIC_CLOCKEVENTS @@ -82,7 +84,7 @@ extern int tick_program_event(ktime_t expires, int force); extern void tick_setup_sched_timer(void); # endif -# if defined CONFIG_NO_HZ || defined CONFIG_HIGH_RES_TIMERS +# if defined CONFIG_NO_HZ_COMMON || defined CONFIG_HIGH_RES_TIMERS extern void tick_cancel_sched_timer(int cpu); # else static inline void tick_cancel_sched_timer(int cpu) { } @@ -123,7 +125,7 @@ static inline void tick_check_idle(int cpu) { } static inline int tick_oneshot_mode_active(void) { return 0; } #endif /* !CONFIG_GENERIC_CLOCKEVENTS */ -# ifdef CONFIG_NO_HZ +# ifdef CONFIG_NO_HZ_COMMON DECLARE_PER_CPU(struct tick_sched, tick_cpu_sched); static inline int tick_nohz_tick_stopped(void) @@ -138,7 +140,7 @@ extern ktime_t tick_nohz_get_sleep_length(void); extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time); extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time); -# else /* !CONFIG_NO_HZ */ +# else /* !CONFIG_NO_HZ_COMMON */ static inline int tick_nohz_tick_stopped(void) { return 0; @@ -155,12 +157,54 @@ static inline ktime_t tick_nohz_get_sleep_length(void) } static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; } static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; } -# endif /* !NO_HZ */ +# endif /* !CONFIG_NO_HZ_COMMON */ + +#ifdef CONFIG_NO_HZ_FULL +extern bool tick_nohz_full_running; +extern cpumask_var_t tick_nohz_full_mask; + +static inline bool tick_nohz_full_enabled(void) +{ + if (!static_key_false(&context_tracking_enabled)) + return false; + + return tick_nohz_full_running; +} + +static inline bool tick_nohz_full_cpu(int cpu) +{ + if (!tick_nohz_full_enabled()) + return false; + + return cpumask_test_cpu(cpu, tick_nohz_full_mask); +} + +extern void tick_nohz_init(void); +extern void __tick_nohz_full_check(void); +extern void tick_nohz_full_kick(void); +extern void tick_nohz_full_kick_all(void); +extern void __tick_nohz_task_switch(struct task_struct *tsk); +#else +static inline void tick_nohz_init(void) { } +static inline bool tick_nohz_full_enabled(void) { return false; } +static inline bool tick_nohz_full_cpu(int cpu) { return false; } +static inline void __tick_nohz_full_check(void) { } +static inline void tick_nohz_full_kick(void) { } +static inline void tick_nohz_full_kick_all(void) { } +static inline void __tick_nohz_task_switch(struct task_struct *tsk) { } +#endif + +static inline void tick_nohz_full_check(void) +{ + if (tick_nohz_full_enabled()) + __tick_nohz_full_check(); +} + +static inline void tick_nohz_task_switch(struct task_struct *tsk) +{ + if (tick_nohz_full_enabled()) + __tick_nohz_task_switch(tsk); +} -# ifdef CONFIG_CPU_IDLE_GOV_MENU -extern void menu_hrtimer_cancel(void); -# else -static inline void menu_hrtimer_cancel(void) {} -# endif /* CONFIG_CPU_IDLE_GOV_MENU */ #endif diff --git a/include/linux/time-armada-370-xp.h b/include/linux/time-armada-370-xp.h deleted file mode 100644 index dfdfdc03115b..000000000000 --- a/include/linux/time-armada-370-xp.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Marvell Armada 370/XP SoC timer handling. - * - * Copyright (C) 2012 Marvell - * - * Lior Amsalem <alior@marvell.com> - * Gregory CLEMENT <gregory.clement@free-electrons.com> - * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> - * - */ -#ifndef __TIME_ARMADA_370_XPPRCMU_H -#define __TIME_ARMADA_370_XPPRCMU_H - -#include <linux/init.h> - -void __init armada_370_xp_timer_init(void); - -#endif diff --git a/include/linux/time.h b/include/linux/time.h index d4835dfdf25e..d5d229b2e5af 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -117,14 +117,10 @@ static inline bool timespec_valid_strict(const struct timespec *ts) extern bool persistent_clock_exist; -#ifdef ALWAYS_USE_PERSISTENT_CLOCK -#define has_persistent_clock() true -#else static inline bool has_persistent_clock(void) { return persistent_clock_exist; } -#endif extern void read_persistent_clock(struct timespec *ts); extern void read_boot_clock(struct timespec *ts); @@ -181,6 +177,9 @@ extern struct timespec timespec_trunc(struct timespec t, unsigned gran); extern int timekeeping_valid_for_hres(void); extern u64 timekeeping_max_deferment(void); extern int timekeeping_inject_offset(struct timespec *ts); +extern s32 timekeeping_get_tai_offset(void); +extern void timekeeping_set_tai_offset(s32 tai_offset); +extern void timekeeping_clocktai(struct timespec *ts); struct tms; extern void do_sys_times(struct tms *); diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h index e1d558e237ec..c1825eb436ed 100644 --- a/include/linux/timekeeper_internal.h +++ b/include/linux/timekeeper_internal.h @@ -20,6 +20,8 @@ struct timekeeper { u32 shift; /* Number of clock cycles in one NTP interval. */ cycle_t cycle_interval; + /* Last cycle value (also stored in clock->cycle_last) */ + cycle_t cycle_last; /* Number of clock shifted nano seconds in one NTP interval. */ u64 xtime_interval; /* shifted nano seconds left over when rounding cycle_interval */ @@ -62,8 +64,11 @@ struct timekeeper { ktime_t offs_boot; /* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */ struct timespec raw_time; - /* Seqlock for all timekeeper values */ - seqlock_t lock; + /* The current UTC to TAI offset in seconds */ + s32 tai_offset; + /* Offset clock monotonic -> clock tai */ + ktime_t offs_tai; + }; static inline struct timespec tk_xtime(struct timekeeper *tk) diff --git a/include/linux/timeriomem-rng.h b/include/linux/timeriomem-rng.h index 3e08a1c86830..46eb27ddbfab 100644 --- a/include/linux/timeriomem-rng.h +++ b/include/linux/timeriomem-rng.h @@ -8,12 +8,7 @@ * published by the Free Software Foundation. */ -#include <linux/completion.h> - struct timeriomem_rng_data { - struct completion completion; - unsigned int present:1; - void __iomem *address; /* measures in usecs */ diff --git a/include/linux/timex.h b/include/linux/timex.h index 5ec87c60b97c..9d3f1a5b6178 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -64,6 +64,20 @@ #include <asm/timex.h> +#ifndef random_get_entropy +/* + * The random_get_entropy() function is used by the /dev/random driver + * in order to extract entropy via the relative unpredictability of + * when an interrupt takes places versus a high speed, fine-grained + * timing source or cycle counter. Since it will be occurred on every + * single interrupt, it must have a very low cost/overhead. + * + * By default we use get_cycles() for this purpose, but individual + * architectures may override this in their asm/timex.h header file. + */ +#define random_get_entropy() get_cycles() +#endif + /* * SHIFT_PLL is used as a dampening factor to define how much we * adjust the frequency correction for a given offset in PLL mode. @@ -125,9 +139,6 @@ extern unsigned long tick_usec; /* USER_HZ period (usec) */ extern unsigned long tick_nsec; /* SHIFTED_HZ period (nsec) */ -extern void ntp_init(void); -extern void ntp_clear(void); - /* Required to safely shift negative values */ #define shift_right(x, s) ({ \ __typeof__(x) __x = (x); \ @@ -140,14 +151,11 @@ extern void ntp_clear(void); #define NTP_INTERVAL_FREQ (HZ) #define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ) -/* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */ -extern u64 ntp_tick_length(void); - -extern int second_overflow(unsigned long secs); extern int do_adjtimex(struct timex *); extern void hardpps(const struct timespec *, const struct timespec *); int read_current_timer(unsigned long *timer_val); +void ntp_notify_cmos_timer(void); /* The clock frequency of the i8253/i8254 PIT */ #define PIT_TICK_RATE 1193182ul diff --git a/include/linux/topology.h b/include/linux/topology.h index d3cf0d6e7712..12ae6ce997d6 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h @@ -106,6 +106,8 @@ int arch_update_cpu_topology(void); .last_balance = jiffies, \ .balance_interval = 1, \ .smt_gain = 1178, /* 15% */ \ + .max_newidle_lb_cost = 0, \ + .next_decay_max_lb_cost = jiffies, \ } #endif #endif /* CONFIG_SCHED_SMT */ @@ -135,6 +137,8 @@ int arch_update_cpu_topology(void); , \ .last_balance = jiffies, \ .balance_interval = 1, \ + .max_newidle_lb_cost = 0, \ + .next_decay_max_lb_cost = jiffies, \ } #endif #endif /* CONFIG_SCHED_MC */ @@ -166,6 +170,8 @@ int arch_update_cpu_topology(void); , \ .last_balance = jiffies, \ .balance_interval = 1, \ + .max_newidle_lb_cost = 0, \ + .next_decay_max_lb_cost = jiffies, \ } #endif diff --git a/include/linux/tpm.h b/include/linux/tpm.h index fcb627ff8d3e..9a9051bb1a03 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -22,6 +22,8 @@ #ifndef __LINUX_TPM_H__ #define __LINUX_TPM_H__ +#define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */ + /* * Chip num is this value or a valid tpm idx */ diff --git a/include/linux/trace_clock.h b/include/linux/trace_clock.h index d563f37e1a1d..1d7ca2739272 100644 --- a/include/linux/trace_clock.h +++ b/include/linux/trace_clock.h @@ -16,6 +16,7 @@ extern u64 notrace trace_clock_local(void); extern u64 notrace trace_clock(void); +extern u64 notrace trace_clock_jiffies(void); extern u64 notrace trace_clock_global(void); extern u64 notrace trace_clock_counter(void); diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 2f322c38bd4d..ebeab360d851 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -145,8 +145,8 @@ static inline void tracepoint_synchronize_unregister(void) TP_PROTO(data_proto), \ TP_ARGS(data_args), \ TP_CONDITION(cond), \ - rcu_idle_exit(), \ - rcu_idle_enter()); \ + rcu_irq_enter(), \ + rcu_irq_exit()); \ } #else #define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args) @@ -378,6 +378,8 @@ static inline void tracepoint_synchronize_unregister(void) #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) #define DEFINE_EVENT(template, name, proto, args) \ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) +#define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)\ + DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) #define DEFINE_EVENT_CONDITION(template, name, proto, \ diff --git a/include/linux/tty.h b/include/linux/tty.h index c75d886b0307..2f47989d8288 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -10,6 +10,8 @@ #include <linux/mutex.h> #include <linux/tty_flags.h> #include <uapi/linux/tty.h> +#include <linux/rwsem.h> +#include <linux/llist.h> @@ -29,9 +31,10 @@ #define __DISABLED_CHAR '\0' struct tty_buffer { - struct tty_buffer *next; - char *char_buf_ptr; - unsigned char *flag_buf_ptr; + union { + struct tty_buffer *next; + struct llist_node free; + }; int used; int size; int commit; @@ -40,25 +43,25 @@ struct tty_buffer { unsigned long data[0]; }; -/* - * We default to dicing tty buffer allocations to this many characters - * in order to avoid multiple page allocations. We know the size of - * tty_buffer itself but it must also be taken into account that the - * the buffer is 256 byte aligned. See tty_buffer_find for the allocation - * logic this must match - */ - -#define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF) +static inline unsigned char *char_buf_ptr(struct tty_buffer *b, int ofs) +{ + return ((unsigned char *)b->data) + ofs; +} +static inline char *flag_buf_ptr(struct tty_buffer *b, int ofs) +{ + return (char *)char_buf_ptr(b, ofs) + b->size; +} struct tty_bufhead { - struct work_struct work; - spinlock_t lock; struct tty_buffer *head; /* Queue head */ + struct work_struct work; + struct mutex lock; + atomic_t priority; + struct tty_buffer sentinel; + struct llist_head free; /* Free queue head */ + atomic_t memory_used; /* In-use buffers excluding free list */ struct tty_buffer *tail; /* Active buffer */ - struct tty_buffer *free; /* Free queue head */ - int memory_used; /* Buffer space used excluding - free queue */ }; /* * When a break, frame error, or parity error happens, these codes are @@ -177,7 +180,6 @@ struct tty_port_operations { IFF the port was initialized. Do not use to free resources. Called under the port mutex to serialize against activate/shutdowns */ void (*shutdown)(struct tty_port *port); - void (*drop)(struct tty_port *port); /* Called under the port mutex from tty_port_open, serialized using the port mutex */ /* FIXME: long term getting the tty argument *out* of this would be @@ -199,9 +201,6 @@ struct tty_port { wait_queue_head_t close_wait; /* Close waiters */ wait_queue_head_t delta_msr_wait; /* Modem status change */ unsigned long flags; /* TTY flags ASY_*/ - unsigned long iflags; /* TTYP_ internal flags */ -#define TTYP_FLUSHING 1 /* Flushing to ldisc in progress */ -#define TTYP_FLUSHPENDING 2 /* Queued buffer flush pending */ unsigned char console:1, /* port is a console */ low_latency:1; /* direct buffer flush */ struct mutex mutex; /* Locking */ @@ -238,14 +237,16 @@ struct tty_struct { int index; /* Protects ldisc changes: Lock tty not pty */ - struct mutex ldisc_mutex; + struct ld_semaphore ldisc_sem; struct tty_ldisc *ldisc; struct mutex atomic_write_lock; struct mutex legacy_mutex; - struct mutex termios_mutex; + struct mutex throttle_mutex; + struct rw_semaphore termios_rwsem; + struct mutex winsize_mutex; spinlock_t ctrl_lock; - /* Termios values are protected by the termios mutex */ + /* Termios values are protected by the termios rwsem */ struct ktermios termios, termios_locked; struct termiox *termiox; /* May be NULL for unsupported */ char name[64]; @@ -253,11 +254,11 @@ struct tty_struct { struct pid *session; unsigned long flags; int count; - struct winsize winsize; /* termios mutex */ + struct winsize winsize; /* winsize_mutex */ unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1; - unsigned char warned:1; unsigned char ctrl_status; /* ctrl_lock */ unsigned int receive_room; /* Bytes free for queue */ + int flow_change; struct tty_struct *link; struct fasync_struct *fasync; @@ -272,7 +273,6 @@ struct tty_struct { #define N_TTY_BUF_SIZE 4096 unsigned char closing:1; - unsigned short minimum_to_wake; unsigned char *write_buf; int write_cnt; /* If the tty has a pending do_SAK, queue it here - akpm */ @@ -304,20 +304,31 @@ struct tty_file_private { #define TTY_EXCLUSIVE 3 /* Exclusive open mode */ #define TTY_DEBUG 4 /* Debugging */ #define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */ -#define TTY_PUSH 6 /* n_tty private */ #define TTY_CLOSING 7 /* ->close() in progress */ -#define TTY_LDISC 9 /* Line discipline attached */ -#define TTY_LDISC_CHANGING 10 /* Line discipline changing */ #define TTY_LDISC_OPEN 11 /* Line discipline is open */ -#define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */ -#define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */ #define TTY_PTY_LOCK 16 /* pty private */ #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ #define TTY_HUPPED 18 /* Post driver->hangup() */ #define TTY_HUPPING 21 /* ->hangup() in progress */ +#define TTY_LDISC_HALTED 22 /* Line discipline is halted */ #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) +/* Values for tty->flow_change */ +#define TTY_THROTTLE_SAFE 1 +#define TTY_UNTHROTTLE_SAFE 2 + +static inline void __tty_set_flow_change(struct tty_struct *tty, int val) +{ + tty->flow_change = val; +} + +static inline void tty_set_flow_change(struct tty_struct *tty, int val) +{ + tty->flow_change = val; + smp_mb(); +} + #ifdef CONFIG_TTY extern void console_init(void); extern void tty_kref_put(struct tty_struct *tty); @@ -400,6 +411,8 @@ extern int tty_write_room(struct tty_struct *tty); extern void tty_driver_flush_buffer(struct tty_struct *tty); extern void tty_throttle(struct tty_struct *tty); extern void tty_unthrottle(struct tty_struct *tty); +extern int tty_throttle_safe(struct tty_struct *tty); +extern int tty_unthrottle_safe(struct tty_struct *tty); extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws); extern void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty); @@ -419,13 +432,28 @@ extern void tty_flush_to_ldisc(struct tty_struct *tty); extern void tty_buffer_free_all(struct tty_port *port); extern void tty_buffer_flush(struct tty_struct *tty); extern void tty_buffer_init(struct tty_port *port); -extern speed_t tty_get_baud_rate(struct tty_struct *tty); extern speed_t tty_termios_baud_rate(struct ktermios *termios); extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); extern void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud); extern void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud); + +/** + * tty_get_baud_rate - get tty bit rates + * @tty: tty to query + * + * Returns the baud rate as an integer for this terminal. The + * termios lock must be held by the caller and the terminal bit + * flags may be updated. + * + * Locking: none + */ +static inline speed_t tty_get_baud_rate(struct tty_struct *tty) +{ + return tty_termios_baud_rate(&tty->termios); +} + extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old); extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b); extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); @@ -502,6 +530,8 @@ extern int tty_port_carrier_raised(struct tty_port *port); extern void tty_port_raise_dtr_rts(struct tty_port *port); extern void tty_port_lower_dtr_rts(struct tty_port *port); extern void tty_port_hangup(struct tty_port *port); +extern void tty_port_tty_hangup(struct tty_port *port, bool check_clocal); +extern void tty_port_tty_wakeup(struct tty_port *port); extern int tty_port_block_til_ready(struct tty_port *port, struct tty_struct *tty, struct file *filp); extern int tty_port_close_start(struct tty_port *port, @@ -526,8 +556,19 @@ extern void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty); extern void tty_ldisc_init(struct tty_struct *tty); extern void tty_ldisc_deinit(struct tty_struct *tty); extern void tty_ldisc_begin(void); -/* This last one is just for the tty layer internals and shouldn't be used elsewhere */ -extern void tty_ldisc_enable(struct tty_struct *tty); + +static inline int tty_ldisc_receive_buf(struct tty_ldisc *ld, unsigned char *p, + char *f, int count) +{ + if (ld->ops->receive_buf2) + count = ld->ops->receive_buf2(ld->tty, p, f, count); + else { + count = min_t(int, count, ld->tty->receive_room); + if (count) + ld->ops->receive_buf(ld->tty, p, f, count); + } + return count; +} /* n_tty.c */ @@ -542,8 +583,7 @@ extern void tty_audit_exit(void); extern void tty_audit_fork(struct signal_struct *sig); extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); extern void tty_audit_push(struct tty_struct *tty); -extern int tty_audit_push_task(struct task_struct *tsk, - kuid_t loginuid, u32 sessionid); +extern int tty_audit_push_current(void); #else static inline void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, size_t size, unsigned icanon) @@ -561,8 +601,7 @@ static inline void tty_audit_fork(struct signal_struct *sig) static inline void tty_audit_push(struct tty_struct *tty) { } -static inline int tty_audit_push_task(struct task_struct *tsk, - kuid_t loginuid, u32 sessionid) +static inline int tty_audit_push_current(void) { return 0; } @@ -658,5 +697,12 @@ do { \ finish_wait(&wq, &__wait); \ } while (0) +#ifdef CONFIG_PROC_FS +extern void proc_tty_register_driver(struct tty_driver *); +extern void proc_tty_unregister_driver(struct tty_driver *); +#else +static inline void proc_tty_register_driver(struct tty_driver *d) {} +static inline void proc_tty_unregister_driver(struct tty_driver *d) {} +#endif #endif diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index e0f252633b47..21ddd7d9ea1f 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -1,6 +1,7 @@ #ifndef _LINUX_TTY_FLIP_H #define _LINUX_TTY_FLIP_H +extern int tty_buffer_space_avail(struct tty_port *port); extern int tty_buffer_request_room(struct tty_port *port, size_t size); extern int tty_insert_flip_string_flags(struct tty_port *port, const unsigned char *chars, const char *flags, size_t size); @@ -18,8 +19,8 @@ static inline int tty_insert_flip_char(struct tty_port *port, { struct tty_buffer *tb = port->buf.tail; if (tb && tb->used < tb->size) { - tb->flag_buf_ptr[tb->used] = flag; - tb->char_buf_ptr[tb->used++] = ch; + *flag_buf_ptr(tb, tb->used) = flag; + *char_buf_ptr(tb, tb->used++) = ch; return 1; } return tty_insert_flip_string_flags(port, &ch, &flag, 1); @@ -31,4 +32,7 @@ static inline int tty_insert_flip_string(struct tty_port *port, return tty_insert_flip_string_fixed_flag(port, chars, TTY_NORMAL, size); } +extern void tty_buffer_lock_exclusive(struct tty_port *port); +extern void tty_buffer_unlock_exclusive(struct tty_port *port); + #endif /* _LINUX_TTY_FLIP_H */ diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 455a0d7bf220..f15c898ff462 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -9,89 +9,89 @@ * * int (*open)(struct tty_struct *); * - * This function is called when the line discipline is associated - * with the tty. The line discipline can use this as an - * opportunity to initialize any state needed by the ldisc routines. - * + * This function is called when the line discipline is associated + * with the tty. The line discipline can use this as an + * opportunity to initialize any state needed by the ldisc routines. + * * void (*close)(struct tty_struct *); * * This function is called when the line discipline is being - * shutdown, either because the tty is being closed or because - * the tty is being changed to use a new line discipline - * + * shutdown, either because the tty is being closed or because + * the tty is being changed to use a new line discipline + * * void (*flush_buffer)(struct tty_struct *tty); * - * This function instructs the line discipline to clear its - * buffers of any input characters it may have queued to be - * delivered to the user mode process. - * + * This function instructs the line discipline to clear its + * buffers of any input characters it may have queued to be + * delivered to the user mode process. + * * ssize_t (*chars_in_buffer)(struct tty_struct *tty); * - * This function returns the number of input characters the line + * This function returns the number of input characters the line * discipline may have queued up to be delivered to the user mode * process. - * + * * ssize_t (*read)(struct tty_struct * tty, struct file * file, * unsigned char * buf, size_t nr); * - * This function is called when the user requests to read from - * the tty. The line discipline will return whatever characters - * it has buffered up for the user. If this function is not - * defined, the user will receive an EIO error. - * + * This function is called when the user requests to read from + * the tty. The line discipline will return whatever characters + * it has buffered up for the user. If this function is not + * defined, the user will receive an EIO error. + * * ssize_t (*write)(struct tty_struct * tty, struct file * file, - * const unsigned char * buf, size_t nr); - * - * This function is called when the user requests to write to the - * tty. The line discipline will deliver the characters to the - * low-level tty device for transmission, optionally performing - * some processing on the characters first. If this function is - * not defined, the user will receive an EIO error. - * + * const unsigned char * buf, size_t nr); + * + * This function is called when the user requests to write to the + * tty. The line discipline will deliver the characters to the + * low-level tty device for transmission, optionally performing + * some processing on the characters first. If this function is + * not defined, the user will receive an EIO error. + * * int (*ioctl)(struct tty_struct * tty, struct file * file, - * unsigned int cmd, unsigned long arg); + * unsigned int cmd, unsigned long arg); * * This function is called when the user requests an ioctl which - * is not handled by the tty layer or the low-level tty driver. - * It is intended for ioctls which affect line discpline - * operation. Note that the search order for ioctls is (1) tty - * layer, (2) tty low-level driver, (3) line discpline. So a - * low-level driver can "grab" an ioctl request before the line - * discpline has a chance to see it. - * + * is not handled by the tty layer or the low-level tty driver. + * It is intended for ioctls which affect line discpline + * operation. Note that the search order for ioctls is (1) tty + * layer, (2) tty low-level driver, (3) line discpline. So a + * low-level driver can "grab" an ioctl request before the line + * discpline has a chance to see it. + * * long (*compat_ioctl)(struct tty_struct * tty, struct file * file, - * unsigned int cmd, unsigned long arg); + * unsigned int cmd, unsigned long arg); * - * Process ioctl calls from 32-bit process on 64-bit system + * Process ioctl calls from 32-bit process on 64-bit system * * void (*set_termios)(struct tty_struct *tty, struct ktermios * old); * - * This function notifies the line discpline that a change has - * been made to the termios structure. - * + * This function notifies the line discpline that a change has + * been made to the termios structure. + * * int (*poll)(struct tty_struct * tty, struct file * file, - * poll_table *wait); + * poll_table *wait); * - * This function is called when a user attempts to select/poll on a - * tty device. It is solely the responsibility of the line - * discipline to handle poll requests. + * This function is called when a user attempts to select/poll on a + * tty device. It is solely the responsibility of the line + * discipline to handle poll requests. * * void (*receive_buf)(struct tty_struct *, const unsigned char *cp, - * char *fp, int count); - * - * This function is called by the low-level tty driver to send - * characters received by the hardware to the line discpline for - * processing. <cp> is a pointer to the buffer of input - * character received by the device. <fp> is a pointer to a - * pointer of flag bytes which indicate whether a character was - * received with a parity error, etc. - * + * char *fp, int count); + * + * This function is called by the low-level tty driver to send + * characters received by the hardware to the line discpline for + * processing. <cp> is a pointer to the buffer of input + * character received by the device. <fp> is a pointer to a + * pointer of flag bytes which indicate whether a character was + * received with a parity error, etc. + * * void (*write_wakeup)(struct tty_struct *); * - * This function is called by the low-level tty driver to signal - * that line discpline should try to send more characters to the - * low-level driver for transmission. If the line discpline does - * not have any more data to send, it can just return. + * This function is called by the low-level tty driver to signal + * that line discpline should try to send more characters to the + * low-level driver for transmission. If the line discpline does + * not have any more data to send, it can just return. * * int (*hangup)(struct tty_struct *) * @@ -100,22 +100,84 @@ * seek to perform this action quickly but should wait until * any pending driver I/O is completed. * + * void (*fasync)(struct tty_struct *, int on) + * + * Notify line discipline when signal-driven I/O is enabled or + * disabled. + * * void (*dcd_change)(struct tty_struct *tty, unsigned int status) * * Tells the discipline that the DCD pin has changed its status. * Used exclusively by the N_PPS (Pulse-Per-Second) line discipline. + * + * int (*receive_buf2)(struct tty_struct *, const unsigned char *cp, + * char *fp, int count); + * + * This function is called by the low-level tty driver to send + * characters received by the hardware to the line discpline for + * processing. <cp> is a pointer to the buffer of input + * character received by the device. <fp> is a pointer to a + * pointer of flag bytes which indicate whether a character was + * received with a parity error, etc. + * If assigned, prefer this function for automatic flow control. */ #include <linux/fs.h> #include <linux/wait.h> #include <linux/wait.h> + +/* + * the semaphore definition + */ +struct ld_semaphore { + long count; + raw_spinlock_t wait_lock; + unsigned int wait_readers; + struct list_head read_wait; + struct list_head write_wait; +#ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lockdep_map dep_map; +#endif +}; + +extern void __init_ldsem(struct ld_semaphore *sem, const char *name, + struct lock_class_key *key); + +#define init_ldsem(sem) \ +do { \ + static struct lock_class_key __key; \ + \ + __init_ldsem((sem), #sem, &__key); \ +} while (0) + + +extern int ldsem_down_read(struct ld_semaphore *sem, long timeout); +extern int ldsem_down_read_trylock(struct ld_semaphore *sem); +extern int ldsem_down_write(struct ld_semaphore *sem, long timeout); +extern int ldsem_down_write_trylock(struct ld_semaphore *sem); +extern void ldsem_up_read(struct ld_semaphore *sem); +extern void ldsem_up_write(struct ld_semaphore *sem); + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +extern int ldsem_down_read_nested(struct ld_semaphore *sem, int subclass, + long timeout); +extern int ldsem_down_write_nested(struct ld_semaphore *sem, int subclass, + long timeout); +#else +# define ldsem_down_read_nested(sem, subclass, timeout) \ + ldsem_down_read(sem, timeout) +# define ldsem_down_write_nested(sem, subclass, timeout) \ + ldsem_down_write(sem, timeout) +#endif + + struct tty_ldisc_ops { int magic; char *name; int num; int flags; - + /* * The following routines are called from above. */ @@ -123,19 +185,19 @@ struct tty_ldisc_ops { void (*close)(struct tty_struct *); void (*flush_buffer)(struct tty_struct *tty); ssize_t (*chars_in_buffer)(struct tty_struct *tty); - ssize_t (*read)(struct tty_struct * tty, struct file * file, - unsigned char __user * buf, size_t nr); - ssize_t (*write)(struct tty_struct * tty, struct file * file, - const unsigned char * buf, size_t nr); - int (*ioctl)(struct tty_struct * tty, struct file * file, + ssize_t (*read)(struct tty_struct *tty, struct file *file, + unsigned char __user *buf, size_t nr); + ssize_t (*write)(struct tty_struct *tty, struct file *file, + const unsigned char *buf, size_t nr); + int (*ioctl)(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); - long (*compat_ioctl)(struct tty_struct * tty, struct file * file, + long (*compat_ioctl)(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); - void (*set_termios)(struct tty_struct *tty, struct ktermios * old); + void (*set_termios)(struct tty_struct *tty, struct ktermios *old); unsigned int (*poll)(struct tty_struct *, struct file *, struct poll_table_struct *); int (*hangup)(struct tty_struct *tty); - + /* * The following routines are called from below. */ @@ -143,16 +205,18 @@ struct tty_ldisc_ops { char *fp, int count); void (*write_wakeup)(struct tty_struct *); void (*dcd_change)(struct tty_struct *, unsigned int); + void (*fasync)(struct tty_struct *tty, int on); + int (*receive_buf2)(struct tty_struct *, const unsigned char *cp, + char *fp, int count); struct module *owner; - + int refcount; }; struct tty_ldisc { struct tty_ldisc_ops *ops; - atomic_t users; - wait_queue_head_t wq_idle; + struct tty_struct *tty; }; #define TTY_LDISC_MAGIC 0x5403 diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 5ca0951e1855..9d8cf056e661 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -15,7 +15,7 @@ */ static inline void pagefault_disable(void) { - inc_preempt_count(); + preempt_count_inc(); /* * make sure to have issued the store before a pagefault * can hit. @@ -30,11 +30,7 @@ static inline void pagefault_enable(void) * the pagefault handler again. */ barrier(); - dec_preempt_count(); - /* - * make sure we do.. - */ - barrier(); + preempt_count_dec(); preempt_check_resched(); } diff --git a/include/linux/ucb1400.h b/include/linux/ucb1400.h index d21b33c4c6ca..2e9ee4d1c676 100644 --- a/include/linux/ucb1400.h +++ b/include/linux/ucb1400.h @@ -83,15 +83,12 @@ #define UCB_ID 0x7e #define UCB_ID_1400 0x4304 -struct ucb1400_gpio_data { - int gpio_offset; - int (*gpio_setup)(struct device *dev, int ngpio); - int (*gpio_teardown)(struct device *dev, int ngpio); -}; - struct ucb1400_gpio { struct gpio_chip gc; struct snd_ac97 *ac97; + int gpio_offset; + int (*gpio_setup)(struct device *dev, int ngpio); + int (*gpio_teardown)(struct device *dev, int ngpio); }; struct ucb1400_ts { @@ -110,6 +107,9 @@ struct ucb1400 { struct ucb1400_pdata { int irq; + int gpio_offset; + int (*gpio_setup)(struct device *dev, int ngpio); + int (*gpio_teardown)(struct device *dev, int ngpio); }; static inline u16 ucb1400_reg_read(struct snd_ac97 *ac97, u16 reg) @@ -162,10 +162,4 @@ static inline void ucb1400_adc_disable(struct snd_ac97 *ac97) unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel, int adcsync); -#ifdef CONFIG_GPIO_UCB1400 -void __init ucb1400_gpio_set_data(struct ucb1400_gpio_data *data); -#else -static inline void ucb1400_gpio_set_data(struct ucb1400_gpio_data *data) {} -#endif - #endif diff --git a/include/linux/ucs2_string.h b/include/linux/ucs2_string.h new file mode 100644 index 000000000000..cbb20afdbc01 --- /dev/null +++ b/include/linux/ucs2_string.h @@ -0,0 +1,14 @@ +#ifndef _LINUX_UCS2_STRING_H_ +#define _LINUX_UCS2_STRING_H_ + +#include <linux/types.h> /* for size_t */ +#include <linux/stddef.h> /* for NULL */ + +typedef u16 ucs2_char_t; + +unsigned long ucs2_strnlen(const ucs2_char_t *s, size_t maxlength); +unsigned long ucs2_strlen(const ucs2_char_t *s); +unsigned long ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength); +int ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len); + +#endif /* _LINUX_UCS2_STRING_H_ */ diff --git a/include/linux/udp.h b/include/linux/udp.h index 9d81de123c90..42278bbf7a88 100644 --- a/include/linux/udp.h +++ b/include/linux/udp.h @@ -68,6 +68,7 @@ struct udp_sock { * For encapsulation sockets. */ int (*encap_rcv)(struct sock *sk, struct sk_buff *skb); + void (*encap_destroy)(struct sock *sk); }; static inline struct udp_sock *udp_sk(const struct sock *sk) diff --git a/include/linux/uio.h b/include/linux/uio.h index 629aaf51f30b..c55ce243cc09 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -35,4 +35,7 @@ static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs) } unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to); + +int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); +int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); #endif diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 02b83db8e2c5..06f28beed7c2 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h @@ -38,6 +38,8 @@ struct inode; #define UPROBE_HANDLER_REMOVE 1 #define UPROBE_HANDLER_MASK 1 +#define MAX_URETPROBE_DEPTH 64 + enum uprobe_filter_ctx { UPROBE_FILTER_REGISTER, UPROBE_FILTER_UNREGISTER, @@ -46,6 +48,9 @@ enum uprobe_filter_ctx { struct uprobe_consumer { int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs); + int (*ret_handler)(struct uprobe_consumer *self, + unsigned long func, + struct pt_regs *regs); bool (*filter)(struct uprobe_consumer *self, enum uprobe_filter_ctx ctx, struct mm_struct *mm); @@ -68,6 +73,8 @@ struct uprobe_task { enum uprobe_task_state state; struct arch_uprobe_task autask; + struct return_instance *return_instances; + unsigned int depth; struct uprobe *active_uprobe; unsigned long xol_vaddr; @@ -100,6 +107,7 @@ struct uprobes_state { extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); extern bool __weak is_swbp_insn(uprobe_opcode_t *insn); +extern bool __weak is_trap_insn(uprobe_opcode_t *insn); extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool); extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); diff --git a/include/linux/usb.h b/include/linux/usb.h index 4d22d0f6167a..f726c39097e0 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -337,6 +337,7 @@ struct usb_bus { * the ep queue on a short transfer * with the URB_SHORT_NOT_OK flag set. */ + unsigned no_sg_constraint:1; /* no sg constraint */ unsigned sg_tablesize; /* 0 or largest number of sg list entries */ int devnum_next; /* Next open device number in @@ -367,17 +368,6 @@ struct usb_bus { /* ----------------------------------------------------------------------- */ -/* This is arbitrary. - * From USB 2.0 spec Table 11-13, offset 7, a hub can - * have up to 255 ports. The most yet reported is 10. - * - * Current Wireless USB host hardware (Intel i1480 for example) allows - * up to 22 devices to connect. Upcoming hardware might raise that - * limit. Because the arrays need to add a bit for hub status data, we - * do 31, so plus one evens out to four bytes. - */ -#define USB_MAXCHILDREN (31) - struct usb_tt; enum usb_device_removable { @@ -394,6 +384,22 @@ enum usb_port_connect_type { }; /* + * USB 2.0 Link Power Management (LPM) parameters. + */ +struct usb2_lpm_parameters { + /* Best effort service latency indicate how long the host will drive + * resume on an exit from L1. + */ + unsigned int besl; + + /* Timeout value in microseconds for the L1 inactivity (LPM) timer. + * When the timer counts to zero, the parent hub will initiate a LPM + * transition to L1. + */ + int timeout; +}; + +/* * USB 3.0 Link Power Management (LPM) parameters. * * PEL and SEL are USB 3.0 Link PM latencies for device-initiated LPM exit. @@ -468,15 +474,14 @@ struct usb3_lpm_parameters { * @wusb: device is Wireless USB * @lpm_capable: device supports LPM * @usb2_hw_lpm_capable: device can perform USB2 hardware LPM + * @usb2_hw_lpm_besl_capable: device can perform USB2 hardware BESL LPM * @usb2_hw_lpm_enabled: USB2 hardware LPM enabled + * @usb3_lpm_enabled: USB3 hardware LPM enabled * @string_langid: language ID for strings * @product: iProduct string, if present (static) * @manufacturer: iManufacturer string, if present (static) * @serial: iSerialNumber string, if present (static) * @filelist: usbfs files that are open to this device - * @usb_classdev: USB class device that was created for usbfs device - * access from userspace - * @usbfs_dentry: usbfs dentry entry for the device * @maxchild: number of ports if hub * @quirks: quirks of the whole device * @urbnum: number of URBs submitted for the whole device @@ -489,6 +494,7 @@ struct usb3_lpm_parameters { * specific data for the device. * @slot_id: Slot ID assigned by xHCI * @removable: Device can be physically removed from this port + * @l1_params: best effor service latency for USB2 L1 LPM state, and L1 timeout. * @u1_params: exit latencies for USB3 U1 LPM state, and hub-initiated timeout. * @u2_params: exit latencies for USB3 U2 LPM state, and hub-initiated timeout. * @lpm_disable_count: Ref count used by usb_disable_lpm() and usb_enable_lpm() @@ -540,6 +546,7 @@ struct usb_device { unsigned wusb:1; unsigned lpm_capable:1; unsigned usb2_hw_lpm_capable:1; + unsigned usb2_hw_lpm_besl_capable:1; unsigned usb2_hw_lpm_enabled:1; unsigned usb3_lpm_enabled:1; int string_langid; @@ -568,6 +575,7 @@ struct usb_device { struct wusb_dev *wusb_dev; int slot_id; enum usb_device_removable removable; + struct usb2_lpm_parameters l1_params; struct usb3_lpm_parameters u1_params; struct usb3_lpm_parameters u2_params; unsigned lpm_disable_count; @@ -619,7 +627,7 @@ static inline bool usb_acpi_power_manageable(struct usb_device *hdev, int index) #endif /* USB autosuspend and autoresume */ -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM_RUNTIME extern void usb_enable_autosuspend(struct usb_device *udev); extern void usb_disable_autosuspend(struct usb_device *udev); @@ -677,6 +685,11 @@ static inline bool usb_device_supports_ltm(struct usb_device *udev) return udev->bos->ss_cap->bmAttributes & USB_LTM_SUPPORT; } +static inline bool usb_device_no_sg_constraint(struct usb_device *udev) +{ + return udev && udev->bus && udev->bus->no_sg_constraint; +} + /*-------------------------------------------------------------------------*/ @@ -689,7 +702,7 @@ extern int usb_alloc_streams(struct usb_interface *interface, unsigned int num_streams, gfp_t mem_flags); /* Reverts a group of bulk endpoints back to not using stream IDs. */ -extern void usb_free_streams(struct usb_interface *interface, +extern int usb_free_streams(struct usb_interface *interface, struct usb_host_endpoint **eps, unsigned int num_eps, gfp_t mem_flags); @@ -701,7 +714,10 @@ extern int usb_driver_claim_interface(struct usb_driver *driver, * usb_interface_claimed - returns true iff an interface is claimed * @iface: the interface being checked * - * Returns true (nonzero) iff the interface is claimed, else false (zero). + * Return: %true (nonzero) iff the interface is claimed, else %false + * (zero). + * + * Note: * Callers must own the driver model's usb bus readlock. So driver * probe() entries don't need extra locking, but other call contexts * may need to explicitly claim that lock. @@ -719,6 +735,7 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface, extern int usb_match_one_id(struct usb_interface *interface, const struct usb_device_id *id); +extern int usb_for_each_dev(void *data, int (*fn)(struct usb_device *, void *)); extern struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor); extern struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev, @@ -737,8 +754,9 @@ extern struct usb_host_interface *usb_find_alt_setting( * @buf: where to put the string * @size: how big is "buf"? * - * Returns length of the string (> 0) or negative if size was too small. + * Return: Length of the string (> 0) or negative if size was too small. * + * Note: * This identifier is intended to be "stable", reflecting physical paths in * hardware such as physical bus addresses for host controllers or ports on * USB hubs. That makes it stay the same until systems are physically @@ -978,7 +996,12 @@ struct usbdrv_wrap { * the "usbfs" filesystem. This lets devices provide ways to * expose information to user space regardless of where they * do (or don't) show up otherwise in the filesystem. - * @suspend: Called when the device is going to be suspended by the system. + * @suspend: Called when the device is going to be suspended by the + * system either from system sleep or runtime suspend context. The + * return value will be ignored in system sleep context, so do NOT + * try to continue using the device if suspend fails in this case. + * Instead, let the resume or reset-resume routine recover from + * the failure. * @resume: Called when the device is being resumed by the system. * @reset_resume: Called when the suspended device has been reset instead * of being resumed. @@ -1234,7 +1257,9 @@ typedef void (*usb_complete_t)(struct urb *); * the device driver is saying that it provided this DMA address, * which the host controller driver should use in preference to the * transfer_buffer. - * @sg: scatter gather buffer list + * @sg: scatter gather buffer list, the buffer size of each element in + * the list (except the last) must be divisible by the endpoint's + * max packet size if no_sg_constraint isn't set in 'struct usb_bus' * @num_mapped_sgs: (internal) number of mapped sg entries * @num_sgs: number of entries in the sg list * @transfer_buffer_length: How big is transfer_buffer. The transfer may @@ -1521,10 +1546,16 @@ static inline void usb_fill_int_urb(struct urb *urb, urb->transfer_buffer_length = buffer_length; urb->complete = complete_fn; urb->context = context; - if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER) + + if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER) { + /* make sure interval is within allowed range */ + interval = clamp(interval, 1, 16); + urb->interval = 1 << (interval - 1); - else + } else { urb->interval = interval; + } + urb->start_frame = -1; } @@ -1557,7 +1588,7 @@ extern int usb_anchor_empty(struct usb_anchor *anchor); * usb_urb_dir_in - check if an URB describes an IN transfer * @urb: URB to be checked * - * Returns 1 if @urb describes an IN transfer (device-to-host), + * Return: 1 if @urb describes an IN transfer (device-to-host), * otherwise 0. */ static inline int usb_urb_dir_in(struct urb *urb) @@ -1569,7 +1600,7 @@ static inline int usb_urb_dir_in(struct urb *urb) * usb_urb_dir_out - check if an URB describes an OUT transfer * @urb: URB to be checked * - * Returns 1 if @urb describes an OUT transfer (host-to-device), + * Return: 1 if @urb describes an OUT transfer (host-to-device), * otherwise 0. */ static inline int usb_urb_dir_out(struct urb *urb) diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h index ed13053153f4..c5f2158ab00e 100644 --- a/include/linux/usb/audio-v2.h +++ b/include/linux/usb/audio-v2.h @@ -170,6 +170,8 @@ struct uac2_as_header_descriptor { __u8 iChannelNames; } __attribute__((packed)); +#define UAC2_FORMAT_TYPE_I_RAW_DATA (1 << 31) + /* 4.10.1.2 Class-Specific AS Isochronous Audio Data Endpoint Descriptor */ struct uac2_iso_endpoint_descriptor { diff --git a/include/linux/usb/cdc-wdm.h b/include/linux/usb/cdc-wdm.h index 719c332620fa..0b3f4295c025 100644 --- a/include/linux/usb/cdc-wdm.h +++ b/include/linux/usb/cdc-wdm.h @@ -11,6 +11,8 @@ #ifndef __LINUX_USB_CDC_WDM_H #define __LINUX_USB_CDC_WDM_H +#include <uapi/linux/usb/cdc-wdm.h> + extern struct usb_driver *usb_cdc_wdm_register(struct usb_interface *intf, struct usb_endpoint_descriptor *ep, int bufsize, diff --git a/include/linux/usb/cdc_ncm.h b/include/linux/usb/cdc_ncm.h index 3b8f9d4fc3fe..cc25b70af33c 100644 --- a/include/linux/usb/cdc_ncm.h +++ b/include/linux/usb/cdc_ncm.h @@ -127,6 +127,7 @@ struct cdc_ncm_ctx { u16 connected; }; +extern u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf); extern int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting); extern void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf); extern struct sk_buff *cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign); diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index 9c210f2283df..27603bcbb9b9 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h @@ -43,4 +43,13 @@ */ extern const char *usb_speed_string(enum usb_device_speed speed); + +/** + * usb_state_string - Returns human readable name for the state. + * @state: The state to return a human-readable name for. If it's not + * any of the states devices in usb_device_state_string enum, + * the string UNKNOWN will be returned. + */ +extern const char *usb_state_string(enum usb_device_state state); + #endif /* __LINUX_USB_CH9_H */ diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index 544825dde823..7d399671a566 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -7,32 +7,38 @@ #include <linux/usb/otg.h> -struct ci13xxx; -struct ci13xxx_platform_data { +struct ci_hdrc; +struct ci_hdrc_platform_data { const char *name; /* offset of the capability registers */ uintptr_t capoffset; unsigned power_budget; struct usb_phy *phy; + enum usb_phy_interface phy_mode; unsigned long flags; -#define CI13XXX_REGS_SHARED BIT(0) -#define CI13XXX_REQUIRE_TRANSCEIVER BIT(1) -#define CI13XXX_PULLUP_ON_VBUS BIT(2) -#define CI13XXX_DISABLE_STREAMING BIT(3) - -#define CI13XXX_CONTROLLER_RESET_EVENT 0 -#define CI13XXX_CONTROLLER_STOPPED_EVENT 1 - void (*notify_event) (struct ci13xxx *ci, unsigned event); +#define CI_HDRC_REGS_SHARED BIT(0) +#define CI_HDRC_REQUIRE_TRANSCEIVER BIT(1) +#define CI_HDRC_DISABLE_STREAMING BIT(3) + /* + * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1, + * but otg is not supported (no register otgsc). + */ +#define CI_HDRC_DUAL_ROLE_NOT_OTG BIT(4) + enum usb_dr_mode dr_mode; +#define CI_HDRC_CONTROLLER_RESET_EVENT 0 +#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 + void (*notify_event) (struct ci_hdrc *ci, unsigned event); + struct regulator *reg_vbus; }; /* Default offset of capability registers */ #define DEF_CAPOFFSET 0x100 -/* Add ci13xxx device */ -struct platform_device *ci13xxx_add_device(struct device *dev, +/* Add ci hdrc device */ +struct platform_device *ci_hdrc_add_device(struct device *dev, struct resource *res, int nres, - struct ci13xxx_platform_data *platdata); -/* Remove ci13xxx device */ -void ci13xxx_remove_device(struct platform_device *pdev); + struct ci_hdrc_platform_data *platdata); +/* Remove ci hdrc device */ +void ci_hdrc_remove_device(struct platform_device *pdev); #endif diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 3c671c1b37f6..5e61589fc166 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -39,6 +39,7 @@ #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> #include <linux/log2.h> +#include <linux/configfs.h> /* * USB function drivers should return USB_GADGET_DELAYED_STATUS if they @@ -60,7 +61,7 @@ struct usb_configuration; * @name: For diagnostics, identifies the function. * @strings: tables of strings, keyed by identifiers assigned during bind() * and by language IDs provided in control requests - * @descriptors: Table of full (or low) speed descriptors, using interface and + * @fs_descriptors: Table of full (or low) speed descriptors, using interface and * string identifiers assigned during @bind(). If this pointer is null, * the function will not be available at full speed (or at low speed). * @hs_descriptors: Table of high speed descriptors, using interface and @@ -290,6 +291,7 @@ enum { * after function notifications * @resume: Notifies configuration when the host restarts USB traffic, * before function notifications + * @gadget_driver: Gadget driver controlling this driver * * Devices default to reporting self powered operation. Devices which rely * on bus powered operation should report this in their @bind method. @@ -463,6 +465,8 @@ struct usb_function_driver { }; struct usb_function_instance { + struct config_group group; + struct list_head cfs_list; struct usb_function_driver *fd; void (*free_func_inst)(struct usb_function_instance *inst); }; diff --git a/include/linux/usb/dwc3-omap.h b/include/linux/usb/dwc3-omap.h deleted file mode 100644 index 51eae14477f7..000000000000 --- a/include/linux/usb/dwc3-omap.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2013 by Texas Instruments - * - * The Inventra Controller Driver for Linux 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 __DWC3_OMAP_H__ -#define __DWC3_OMAP_H__ - -enum omap_dwc3_vbus_id_status { - OMAP_DWC3_UNKNOWN = 0, - OMAP_DWC3_ID_GROUND, - OMAP_DWC3_ID_FLOAT, - OMAP_DWC3_VBUS_VALID, - OMAP_DWC3_VBUS_OFF, -}; - -#if (defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_DWC3_MODULE)) -extern void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status); -#else -static inline void dwc3_omap_mailbox(enum omap_dwc3_vbus_id_status status) -{ - return; -} -#endif - -#endif /* __DWC3_OMAP_H__ */ diff --git a/include/linux/usb/ehci_pdriver.h b/include/linux/usb/ehci_pdriver.h index 99238b096f7e..7eb4dcd0d386 100644 --- a/include/linux/usb/ehci_pdriver.h +++ b/include/linux/usb/ehci_pdriver.h @@ -19,6 +19,9 @@ #ifndef __USB_CORE_EHCI_PDRIVER_H #define __USB_CORE_EHCI_PDRIVER_H +struct platform_device; +struct usb_hcd; + /** * struct usb_ehci_pdata - platform_data for generic ehci driver * @@ -50,6 +53,7 @@ struct usb_ehci_pdata { /* Turn on only VBUS suspend power and hotplug detection, * turn off everything else */ void (*power_suspend)(struct platform_device *pdev); + int (*pre_setup)(struct usb_hcd *hcd); }; #endif /* __USB_CORE_EHCI_PDRIVER_H */ diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 2e297e80d59a..942ef5e053bf 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -22,6 +22,7 @@ #include <linux/slab.h> #include <linux/scatterlist.h> #include <linux/types.h> +#include <linux/workqueue.h> #include <linux/usb/ch9.h> struct usb_ep; @@ -475,6 +476,7 @@ struct usb_gadget_ops { /** * struct usb_gadget - represents a usb slave device + * @work: (internal use) Workqueue to be used for sysfs_notify() * @ops: Function pointers used to access hardware-specific operations. * @ep0: Endpoint zero, used when reading or writing responses to * driver setup() requests @@ -482,6 +484,7 @@ struct usb_gadget_ops { * @speed: Speed of current connection to USB host. * @max_speed: Maximal speed the UDC can handle. UDC must support this * and all slower speeds. + * @state: the state we are now (attached, suspended, configured, etc) * @sg_supported: true if we can handle scatter-gather * @is_otg: True if the USB device port uses a Mini-AB jack, so that the * gadget driver must provide a USB OTG descriptor. @@ -519,12 +522,14 @@ struct usb_gadget_ops { * device is acting as a B-Peripheral (so is_a_peripheral is false). */ struct usb_gadget { + struct work_struct work; /* readonly to gadget driver */ const struct usb_gadget_ops *ops; struct usb_ep *ep0; struct list_head ep_list; /* of usb_ep */ enum usb_device_speed speed; enum usb_device_speed max_speed; + enum usb_device_state state; unsigned sg_supported:1; unsigned is_otg:1; unsigned is_a_peripheral:1; @@ -536,6 +541,7 @@ struct usb_gadget { unsigned out_epnum; unsigned in_epnum; }; +#define work_to_gadget(w) (container_of((w), struct usb_gadget, work)) static inline void set_gadget_data(struct usb_gadget *gadget, void *data) { dev_set_drvdata(&gadget->dev, data); } @@ -561,9 +567,8 @@ static inline int gadget_is_dualspeed(struct usb_gadget *g) } /** - * gadget_is_superspeed() - return true if the hardware handles - * supperspeed - * @g: controller that might support supper speed + * gadget_is_superspeed() - return true if the hardware handles superspeed + * @g: controller that might support superspeed */ static inline int gadget_is_superspeed(struct usb_gadget *g) { @@ -872,6 +877,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver); */ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver); +extern int usb_add_gadget_udc_release(struct device *parent, + struct usb_gadget *gadget, void (*release)(struct device *dev)); extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget); extern void usb_del_gadget_udc(struct usb_gadget *gadget); extern int udc_attach_driver(const char *name, @@ -959,6 +966,13 @@ extern void usb_gadget_unmap_request(struct usb_gadget *gadget, /*-------------------------------------------------------------------------*/ +/* utility to set gadget state properly */ + +extern void usb_gadget_set_state(struct usb_gadget *gadget, + enum usb_device_state state); + +/*-------------------------------------------------------------------------*/ + /* utility wrapping a simple endpoint selection policy */ extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, diff --git a/include/linux/usb/gadget_configfs.h b/include/linux/usb/gadget_configfs.h new file mode 100644 index 000000000000..d74c0ae989d5 --- /dev/null +++ b/include/linux/usb/gadget_configfs.h @@ -0,0 +1,110 @@ +#ifndef __GADGET_CONFIGFS__ +#define __GADGET_CONFIGFS__ + +#include <linux/configfs.h> + +int check_user_usb_string(const char *name, + struct usb_gadget_strings *stringtab_dev); + +#define GS_STRINGS_W(__struct, __name) \ + static ssize_t __struct##_##__name##_store(struct __struct *gs, \ + const char *page, size_t len) \ +{ \ + int ret; \ + \ + ret = usb_string_copy(page, &gs->__name); \ + if (ret) \ + return ret; \ + return len; \ +} + +#define GS_STRINGS_R(__struct, __name) \ + static ssize_t __struct##_##__name##_show(struct __struct *gs, \ + char *page) \ +{ \ + return sprintf(page, "%s\n", gs->__name ?: ""); \ +} + +#define GS_STRING_ITEM_ATTR(struct_name, name) \ + static struct struct_name##_attribute struct_name##_##name = \ + __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \ + struct_name##_##name##_show, \ + struct_name##_##name##_store) + +#define GS_STRINGS_RW(struct_name, _name) \ + GS_STRINGS_R(struct_name, _name) \ + GS_STRINGS_W(struct_name, _name) \ + GS_STRING_ITEM_ATTR(struct_name, _name) + +#define USB_CONFIG_STRING_RW_OPS(struct_in) \ + CONFIGFS_ATTR_OPS(struct_in); \ + \ +static struct configfs_item_operations struct_in##_langid_item_ops = { \ + .release = struct_in##_attr_release, \ + .show_attribute = struct_in##_attr_show, \ + .store_attribute = struct_in##_attr_store, \ +}; \ + \ +static struct config_item_type struct_in##_langid_type = { \ + .ct_item_ops = &struct_in##_langid_item_ops, \ + .ct_attrs = struct_in##_langid_attrs, \ + .ct_owner = THIS_MODULE, \ +} + +#define USB_CONFIG_STRINGS_LANG(struct_in, struct_member) \ + static struct config_group *struct_in##_strings_make( \ + struct config_group *group, \ + const char *name) \ + { \ + struct struct_member *gi; \ + struct struct_in *gs; \ + struct struct_in *new; \ + int langs = 0; \ + int ret; \ + \ + new = kzalloc(sizeof(*new), GFP_KERNEL); \ + if (!new) \ + return ERR_PTR(-ENOMEM); \ + \ + ret = check_user_usb_string(name, &new->stringtab_dev); \ + if (ret) \ + goto err; \ + config_group_init_type_name(&new->group, name, \ + &struct_in##_langid_type); \ + \ + gi = container_of(group, struct struct_member, strings_group); \ + ret = -EEXIST; \ + list_for_each_entry(gs, &gi->string_list, list) { \ + if (gs->stringtab_dev.language == new->stringtab_dev.language) \ + goto err; \ + langs++; \ + } \ + ret = -EOVERFLOW; \ + if (langs >= MAX_USB_STRING_LANGS) \ + goto err; \ + \ + list_add_tail(&new->list, &gi->string_list); \ + return &new->group; \ +err: \ + kfree(new); \ + return ERR_PTR(ret); \ +} \ + \ +static void struct_in##_strings_drop( \ + struct config_group *group, \ + struct config_item *item) \ +{ \ + config_item_put(item); \ +} \ + \ +static struct configfs_group_operations struct_in##_strings_ops = { \ + .make_group = &struct_in##_strings_make, \ + .drop_item = &struct_in##_strings_drop, \ +}; \ + \ +static struct config_item_type struct_in##_strings_type = { \ + .ct_group_ops = &struct_in##_strings_ops, \ + .ct_owner = THIS_MODULE, \ +} + +#endif diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 0a78df5f6cfd..fc64b6825f5e 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -22,6 +22,7 @@ #ifdef __KERNEL__ #include <linux/rwsem.h> +#include <linux/interrupt.h> #define MAX_TOPO_LEVEL 6 @@ -67,6 +68,14 @@ /*-------------------------------------------------------------------------*/ +struct giveback_urb_bh { + bool running; + spinlock_t lock; + struct list_head head; + struct tasklet_struct bh; + struct usb_host_endpoint *completing_ep; +}; + struct usb_hcd { /* @@ -84,7 +93,7 @@ struct usb_hcd { struct timer_list rh_timer; /* drives root-hub polling */ struct urb *status_urb; /* the current status urb */ -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM_RUNTIME struct work_struct wakeup_work; /* for remote wakeup */ #endif @@ -132,6 +141,7 @@ struct usb_hcd { unsigned wireless:1; /* Wireless USB HCD */ unsigned authorized_default:1; unsigned has_tt:1; /* Integrated TT in root hub */ + unsigned amd_resume_bug:1; /* AMD remote wakeup quirk */ unsigned int irq; /* irq allocated */ void __iomem *regs; /* device memory/io */ @@ -139,6 +149,9 @@ struct usb_hcd { resource_size_t rsrc_len; /* memory/io resource length */ unsigned power_budget; /* in mA, 0 = no limit */ + struct giveback_urb_bh high_prio_bh; + struct giveback_urb_bh low_prio_bh; + /* bandwidth_mutex should be taken before adding or removing * any new bus bandwidth constraints: * 1. Before adding a configuration for a new device. @@ -218,8 +231,10 @@ struct hc_driver { #define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */ #define HCD_USB11 0x0010 /* USB 1.1 */ #define HCD_USB2 0x0020 /* USB 2.0 */ +#define HCD_USB25 0x0030 /* Wireless USB 1.0 (USB 2.5)*/ #define HCD_USB3 0x0040 /* USB 3.0 */ #define HCD_MASK 0x0070 +#define HCD_BH 0x0100 /* URB complete in BH context */ /* called to init HCD and root hub */ int (*reset) (struct usb_hcd *hcd); @@ -357,8 +372,20 @@ struct hc_driver { */ int (*disable_usb3_lpm_timeout)(struct usb_hcd *, struct usb_device *, enum usb3_link_state state); + int (*find_raw_port_number)(struct usb_hcd *, int); }; +static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd) +{ + return hcd->driver->flags & HCD_BH; +} + +static inline bool hcd_periodic_completion_in_progress(struct usb_hcd *hcd, + struct usb_host_endpoint *ep) +{ + return hcd->high_prio_bh.completing_ep == ep; +} + extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, int status); @@ -396,6 +423,7 @@ extern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd); extern int usb_add_hcd(struct usb_hcd *hcd, unsigned int irqnum, unsigned long irqflags); extern void usb_remove_hcd(struct usb_hcd *hcd); +extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1); struct platform_device; extern void usb_hcd_platform_shutdown(struct platform_device *dev); @@ -408,7 +436,9 @@ extern int usb_hcd_pci_probe(struct pci_dev *dev, extern void usb_hcd_pci_remove(struct pci_dev *dev); extern void usb_hcd_pci_shutdown(struct pci_dev *dev); -#ifdef CONFIG_PM_SLEEP +extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev); + +#ifdef CONFIG_PM extern const struct dev_pm_ops usb_hcd_pci_pm_ops; #endif #endif /* CONFIG_PCI */ @@ -591,14 +621,14 @@ extern int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg); extern int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg); #endif /* CONFIG_PM */ -#ifdef CONFIG_USB_SUSPEND +#ifdef CONFIG_PM_RUNTIME extern void usb_hcd_resume_root_hub(struct usb_hcd *hcd); #else static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd) { return; } -#endif /* CONFIG_USB_SUSPEND */ +#endif /* CONFIG_PM_RUNTIME */ /*-------------------------------------------------------------------------*/ diff --git a/include/linux/irqchip/sunxi.h b/include/linux/usb/musb-ux500.h index 1fe2c2260e2b..1e2c7130f6e1 100644 --- a/include/linux/irqchip/sunxi.h +++ b/include/linux/usb/musb-ux500.h @@ -1,7 +1,5 @@ /* - * Copyright 2012 Maxime Ripard - * - * Maxime Ripard <maxime.ripard@free-electrons.com> + * Copyright (C) 2013 ST-Ericsson AB * * 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 @@ -14,14 +12,20 @@ * GNU General Public License for more details. */ -#ifndef __LINUX_IRQCHIP_SUNXI_H -#define __LINUX_IRQCHIP_SUNXI_H - -#include <asm/exception.h> - -extern void sunxi_init_irq(void); +#ifndef __MUSB_UX500_H__ +#define __MUSB_UX500_H__ -extern asmlinkage void __exception_irq_entry sunxi_handle_irq( - struct pt_regs *regs); +enum ux500_musb_vbus_id_status { + UX500_MUSB_NONE = 0, + UX500_MUSB_VBUS, + UX500_MUSB_ID, + UX500_MUSB_CHARGER, + UX500_MUSB_ENUMERATED, + UX500_MUSB_RIDA, + UX500_MUSB_RIDB, + UX500_MUSB_RIDC, + UX500_MUSB_PREPARE, + UX500_MUSB_CLEAN, +}; -#endif +#endif /* __MUSB_UX500_H__ */ diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h new file mode 100644 index 000000000000..8c38aa26b3bb --- /dev/null +++ b/include/linux/usb/of.h @@ -0,0 +1,40 @@ +/* + * OF helpers for usb devices. + * + * This file is released under the GPLv2 + */ + +#ifndef __LINUX_USB_OF_H +#define __LINUX_USB_OF_H + +#include <linux/usb/ch9.h> +#include <linux/usb/otg.h> +#include <linux/usb/phy.h> + +#if IS_ENABLED(CONFIG_OF) +enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np); +enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np); +#else +static inline enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np) +{ + return USB_DR_MODE_UNKNOWN; +} + +static inline enum usb_device_speed +of_usb_get_maximum_speed(struct device_node *np) +{ + return USB_SPEED_UNKNOWN; +} +#endif + +#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_USB_SUPPORT) +enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np); +#else +static inline enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np) +{ + return USBPHY_INTERFACE_MODE_UNKNOWN; +} + +#endif + +#endif /* __LINUX_USB_OF_H */ diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index e8a5fe87c6bd..154332b7c8c0 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -36,14 +36,7 @@ struct usb_otg { }; -#ifdef CONFIG_USB_OTG_UTILS -extern const char *otg_state_string(enum usb_otg_state state); -#else -static inline const char *otg_state_string(enum usb_otg_state state) -{ - return NULL; -} -#endif +extern const char *usb_otg_state_string(enum usb_otg_state state); /* Context: can sleep */ static inline int @@ -99,4 +92,11 @@ otg_start_srp(struct usb_otg *otg) /* for OTG controller drivers (and maybe other stuff) */ extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num); +enum usb_dr_mode { + USB_DR_MODE_UNKNOWN, + USB_DR_MODE_HOST, + USB_DR_MODE_PERIPHERAL, + USB_DR_MODE_OTG, +}; + #endif /* __LINUX_USB_OTG_H */ diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index 15847cbdb512..6c0b1c513db7 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -12,6 +12,15 @@ #include <linux/notifier.h> #include <linux/usb.h> +enum usb_phy_interface { + USBPHY_INTERFACE_MODE_UNKNOWN, + USBPHY_INTERFACE_MODE_UTMI, + USBPHY_INTERFACE_MODE_UTMIW, + USBPHY_INTERFACE_MODE_ULPI, + USBPHY_INTERFACE_MODE_SERIAL, + USBPHY_INTERFACE_MODE_HSIC, +}; + enum usb_phy_events { USB_EVENT_NONE, /* no events or cable disconnected */ USB_EVENT_VBUS, /* vbus valid event */ @@ -91,6 +100,9 @@ struct usb_phy { int (*init)(struct usb_phy *x); void (*shutdown)(struct usb_phy *x); + /* enable/disable VBUS */ + int (*set_vbus)(struct usb_phy *x, int on); + /* effective for B devices, ignored for A-peripheral */ int (*set_power)(struct usb_phy *x, unsigned mA); @@ -130,7 +142,7 @@ extern void usb_remove_phy(struct usb_phy *); /* helpers for direct access thru low-level io interface */ static inline int usb_phy_io_read(struct usb_phy *x, u32 reg) { - if (x->io_ops && x->io_ops->read) + if (x && x->io_ops && x->io_ops->read) return x->io_ops->read(x, reg); return -EINVAL; @@ -138,7 +150,7 @@ static inline int usb_phy_io_read(struct usb_phy *x, u32 reg) static inline int usb_phy_io_write(struct usb_phy *x, u32 val, u32 reg) { - if (x->io_ops && x->io_ops->write) + if (x && x->io_ops && x->io_ops->write) return x->io_ops->write(x, val, reg); return -EINVAL; @@ -147,7 +159,7 @@ static inline int usb_phy_io_write(struct usb_phy *x, u32 val, u32 reg) static inline int usb_phy_init(struct usb_phy *x) { - if (x->init) + if (x && x->init) return x->init(x); return 0; @@ -156,12 +168,30 @@ usb_phy_init(struct usb_phy *x) static inline void usb_phy_shutdown(struct usb_phy *x) { - if (x->shutdown) + if (x && x->shutdown) x->shutdown(x); } +static inline int +usb_phy_vbus_on(struct usb_phy *x) +{ + if (!x || !x->set_vbus) + return 0; + + return x->set_vbus(x, true); +} + +static inline int +usb_phy_vbus_off(struct usb_phy *x) +{ + if (!x || !x->set_vbus) + return 0; + + return x->set_vbus(x, false); +} + /* for usb host and peripheral controller drivers */ -#ifdef CONFIG_USB_OTG_UTILS +#if IS_ENABLED(CONFIG_USB_PHY) extern struct usb_phy *usb_get_phy(enum usb_phy_type type); extern struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type); @@ -176,29 +206,29 @@ extern int usb_bind_phy(const char *dev_name, u8 index, #else static inline struct usb_phy *usb_get_phy(enum usb_phy_type type) { - return NULL; + return ERR_PTR(-ENXIO); } static inline struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type) { - return NULL; + return ERR_PTR(-ENXIO); } static inline struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) { - return NULL; + return ERR_PTR(-ENXIO); } static inline struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index) { - return NULL; + return ERR_PTR(-ENXIO); } static inline struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, const char *phandle, u8 index) { - return NULL; + return ERR_PTR(-ENXIO); } static inline void usb_put_phy(struct usb_phy *x) @@ -228,7 +258,7 @@ usb_phy_set_power(struct usb_phy *x, unsigned mA) static inline int usb_phy_set_suspend(struct usb_phy *x, int suspend) { - if (x->set_suspend != NULL) + if (x && x->set_suspend != NULL) return x->set_suspend(x, suspend); else return 0; @@ -237,7 +267,7 @@ usb_phy_set_suspend(struct usb_phy *x, int suspend) static inline int usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed) { - if (x->notify_connect) + if (x && x->notify_connect) return x->notify_connect(x, speed); else return 0; @@ -246,7 +276,7 @@ usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed) static inline int usb_phy_notify_disconnect(struct usb_phy *x, enum usb_device_speed speed) { - if (x->notify_disconnect) + if (x && x->notify_disconnect) return x->notify_disconnect(x, speed); else return 0; diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index c5d36c65c33b..e452ba6ec6bd 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h @@ -62,14 +62,14 @@ struct renesas_usbhs_platform_callback { * Hardware exit function for platform. * it is called when driver was removed */ - void (*hardware_exit)(struct platform_device *pdev); + int (*hardware_exit)(struct platform_device *pdev); /* * option: * * for board specific clock control */ - void (*power_ctrl)(struct platform_device *pdev, + int (*power_ctrl)(struct platform_device *pdev, void __iomem *base, int enable); /* @@ -77,7 +77,7 @@ struct renesas_usbhs_platform_callback { * * Phy reset for platform */ - void (*phy_reset)(struct platform_device *pdev); + int (*phy_reset)(struct platform_device *pdev); /* * get USB ID function diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index ef9be7e1e190..d528b8045150 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -15,13 +15,10 @@ #include <linux/kref.h> #include <linux/mutex.h> +#include <linux/serial.h> #include <linux/sysrq.h> #include <linux/kfifo.h> -#define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ -#define SERIAL_TTY_MINORS 254 /* loads of devices :) */ -#define SERIAL_TTY_NO_MINOR 255 /* No minor was assigned */ - /* The maximum number of ports one device can grab at once */ #define MAX_NUM_PORTS 8 @@ -36,7 +33,8 @@ * @serial: pointer back to the struct usb_serial owner of this port. * @port: pointer to the corresponding tty_port for this port. * @lock: spinlock to grab when updating portions of this structure. - * @number: the number of the port (the minor number). + * @minor: the minor number of the port + * @port_number: the struct usb_serial port number of this port (starts at 0) * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. * @interrupt_in_urb: pointer to the interrupt in struct urb for this port. * @interrupt_in_endpointAddress: endpoint address for the interrupt in pipe @@ -61,6 +59,7 @@ * @bulk_out_buffers: pointers to the bulk out buffers for this port * @write_urbs: pointers to the bulk out urbs for this port * @write_urbs_free: status bitmap the for bulk out urbs + * @icount: interrupt counters * @tx_bytes: number of bytes currently in host stack queues * @bulk_out_endpointAddress: endpoint address for the bulk out pipe for this * port. @@ -78,7 +77,8 @@ struct usb_serial_port { struct usb_serial *serial; struct tty_port port; spinlock_t lock; - unsigned char number; + u32 minor; + u8 port_number; unsigned char *interrupt_in_buffer; struct urb *interrupt_in_urb; @@ -108,6 +108,7 @@ struct usb_serial_port { unsigned long write_urbs_free; __u8 bulk_out_endpointAddress; + struct async_icount icount; int tx_bytes; unsigned long flags; @@ -137,7 +138,6 @@ static inline void usb_set_serial_port_data(struct usb_serial_port *port, * @dev: pointer to the struct usb_device for this device * @type: pointer to the struct usb_serial_driver for this device * @interface: pointer to the struct usb_interface for this device - * @minor: the starting minor number for this device * @num_ports: the number of ports this device has * @num_interrupt_in: number of interrupt in endpoints we have * @num_interrupt_out: number of interrupt out endpoints we have @@ -156,7 +156,7 @@ struct usb_serial { unsigned char disconnected:1; unsigned char suspending:1; unsigned char attached:1; - unsigned char minor; + unsigned char minors_reserved:1; unsigned char num_ports; unsigned char num_port_pointers; char num_interrupt_in; @@ -265,11 +265,14 @@ struct usb_serial_driver { struct usb_serial_port *port, struct ktermios *old); void (*break_ctl)(struct tty_struct *tty, int break_state); int (*chars_in_buffer)(struct tty_struct *tty); + void (*wait_until_sent)(struct tty_struct *tty, long timeout); + bool (*tx_empty)(struct usb_serial_port *port); void (*throttle)(struct tty_struct *tty); void (*unthrottle)(struct tty_struct *tty); int (*tiocmget)(struct tty_struct *tty); int (*tiocmset)(struct tty_struct *tty, unsigned int set, unsigned int clear); + int (*tiocmiwait)(struct tty_struct *tty, unsigned long arg); int (*get_icount)(struct tty_struct *tty, struct serial_icounter_struct *icount); /* Called by the tty layer for port level work. There may or may not @@ -313,7 +316,7 @@ static inline void usb_serial_console_disconnect(struct usb_serial *serial) {} #endif /* Functions needed by other parts of the usbserial core */ -extern struct usb_serial *usb_serial_get_by_index(unsigned int minor); +extern struct usb_serial_port *usb_serial_port_get_by_minor(unsigned int minor); extern void usb_serial_put(struct usb_serial *serial); extern int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port); @@ -323,12 +326,16 @@ extern void usb_serial_generic_close(struct usb_serial_port *port); extern int usb_serial_generic_resume(struct usb_serial *serial); extern int usb_serial_generic_write_room(struct tty_struct *tty); extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty); +extern void usb_serial_generic_wait_until_sent(struct tty_struct *tty, + long timeout); extern void usb_serial_generic_read_bulk_callback(struct urb *urb); extern void usb_serial_generic_write_bulk_callback(struct urb *urb); extern void usb_serial_generic_throttle(struct tty_struct *tty); extern void usb_serial_generic_unthrottle(struct tty_struct *tty); -extern void usb_serial_generic_disconnect(struct usb_serial *serial); -extern void usb_serial_generic_release(struct usb_serial *serial); +extern int usb_serial_generic_tiocmiwait(struct tty_struct *tty, + unsigned long arg); +extern int usb_serial_generic_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount); extern int usb_serial_generic_register(void); extern void usb_serial_generic_deregister(void); extern int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, diff --git a/include/linux/usb/tegra_usb_phy.h b/include/linux/usb/tegra_usb_phy.h index 9ebebe906925..1de16c324ec8 100644 --- a/include/linux/usb/tegra_usb_phy.h +++ b/include/linux/usb/tegra_usb_phy.h @@ -18,19 +18,36 @@ #include <linux/clk.h> #include <linux/usb/otg.h> +/* + * utmi_pll_config_in_car_module: true if the UTMI PLL configuration registers + * should be set up by clk-tegra, false if by the PHY code + * has_hostpc: true if the USB controller has the HOSTPC extension, which + * changes the location of the PHCD and PTS fields + * requires_usbmode_setup: true if the USBMODE register needs to be set to + * enter host mode + * requires_extra_tuning_parameters: true if xcvr_hsslew, hssquelch_level + * and hsdiscon_level should be set for adequate signal quality + */ + +struct tegra_phy_soc_config { + bool utmi_pll_config_in_car_module; + bool has_hostpc; + bool requires_usbmode_setup; + bool requires_extra_tuning_parameters; +}; + struct tegra_utmip_config { u8 hssync_start_delay; u8 elastic_limit; u8 idle_wait_delay; u8 term_range_adj; + bool xcvr_setup_use_fuses; u8 xcvr_setup; u8 xcvr_lsfslew; u8 xcvr_lsrslew; -}; - -struct tegra_ulpi_config { - int reset_gpio; - const char *clk; + u8 xcvr_hsslew; + u8 hssquelch_level; + u8 hsdiscon_level; }; enum tegra_usb_phy_port_speed { @@ -39,11 +56,6 @@ enum tegra_usb_phy_port_speed { TEGRA_USB_PHY_PORT_SPEED_HIGH, }; -enum tegra_usb_phy_mode { - TEGRA_USB_PHY_MODE_DEVICE, - TEGRA_USB_PHY_MODE_HOST, -}; - struct tegra_xtal_freq; struct tegra_usb_phy { @@ -54,18 +66,17 @@ struct tegra_usb_phy { struct clk *clk; struct clk *pll_u; struct clk *pad_clk; - enum tegra_usb_phy_mode mode; + struct regulator *vbus; + enum usb_dr_mode mode; void *config; + const struct tegra_phy_soc_config *soc_config; struct usb_phy *ulpi; struct usb_phy u_phy; - struct device *dev; bool is_legacy_phy; bool is_ulpi_phy; + int reset_gpio; }; -struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance, - void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode); - void tegra_usb_phy_preresume(struct usb_phy *phy); void tegra_usb_phy_postresume(struct usb_phy *phy); @@ -75,8 +86,4 @@ void tegra_ehci_phy_restore_start(struct usb_phy *phy, void tegra_ehci_phy_restore_end(struct usb_phy *phy); -void tegra_ehci_set_pts(struct usb_phy *x, u8 pts_val); - -void tegra_ehci_set_phcd(struct usb_phy *x, bool enable); - #endif /* __TEGRA_USB_PHY_H */ diff --git a/include/linux/usb/ulpi.h b/include/linux/usb/ulpi.h index 6f033a415ecb..5c295c26ad37 100644 --- a/include/linux/usb/ulpi.h +++ b/include/linux/usb/ulpi.h @@ -181,8 +181,16 @@ /*-------------------------------------------------------------------------*/ +#if IS_ENABLED(CONFIG_USB_ULPI) struct usb_phy *otg_ulpi_create(struct usb_phy_io_ops *ops, unsigned int flags); +#else +static inline struct usb_phy *otg_ulpi_create(struct usb_phy_io_ops *ops, + unsigned int flags) +{ + return NULL; +} +#endif #ifdef CONFIG_USB_ULPI_VIEWPORT /* access ops for controllers with a viewport register */ diff --git a/include/linux/usb/nop-usb-xceiv.h b/include/linux/usb/usb_phy_gen_xceiv.h index 28884c717411..f9a7e7bc925b 100644 --- a/include/linux/usb/nop-usb-xceiv.h +++ b/include/linux/usb/usb_phy_gen_xceiv.h @@ -3,11 +3,16 @@ #include <linux/usb/otg.h> -struct nop_usb_xceiv_platform_data { +struct usb_phy_gen_xceiv_platform_data { enum usb_phy_type type; + unsigned long clk_rate; + + /* if set fails with -EPROBE_DEFER if can't get regulator */ + unsigned int needs_vcc:1; + unsigned int needs_reset:1; }; -#if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE)) +#if IS_ENABLED(CONFIG_NOP_USB_XCEIV) /* sometimes transceivers are accessed only through e.g. ULPI */ extern void usb_nop_xceiv_register(void); extern void usb_nop_xceiv_unregister(void); diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 0e5ac93bab10..9cb2fe8ca944 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -34,6 +34,8 @@ struct usbnet { struct mutex phy_mutex; unsigned char suspend_count; unsigned char pkt_cnt, pkt_err; + unsigned short rx_qlen, tx_qlen; + unsigned can_dma_sg:1; /* i/o info: pipes etc */ unsigned in, out; @@ -56,6 +58,8 @@ struct usbnet { struct sk_buff_head done; struct sk_buff_head rxq_pause; struct urb *interrupt; + unsigned interrupt_count; + struct mutex interrupt_mutex; struct usb_anchor deferred; struct tasklet_struct bh; @@ -72,6 +76,7 @@ struct usbnet { # define EVENT_DEVICE_REPORT_IDLE 8 # define EVENT_NO_RUNTIME_PM 9 # define EVENT_RX_KILL 10 +# define EVENT_LINK_CHANGE 11 }; static inline struct usb_driver *driver_of(struct usb_interface *intf) @@ -245,5 +250,11 @@ extern void usbnet_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); extern int usbnet_nway_reset(struct net_device *net); extern int usbnet_manage_power(struct usbnet *, int); +extern void usbnet_link_change(struct usbnet *, bool, bool); + +extern int usbnet_status_start(struct usbnet *dev, gfp_t mem_flags); +extern void usbnet_status_stop(struct usbnet *dev); + +extern void usbnet_update_max_qlen(struct usbnet *dev); #endif /* __LINUX_USB_USBNET_H */ diff --git a/include/linux/usb/wusb-wa.h b/include/linux/usb/wusb-wa.h index f9dec37f617b..4ff744e2b678 100644 --- a/include/linux/usb/wusb-wa.h +++ b/include/linux/usb/wusb-wa.h @@ -66,6 +66,7 @@ enum { WA_ENABLE = 0x01, WA_RESET = 0x02, RPIPE_PAUSE = 0x1, + RPIPE_STALL = 0x2, }; /* Responses from Get Status request ([WUSB] section 8.3.1.6) */ @@ -92,11 +93,20 @@ struct usb_rpipe_descriptor { __le16 wRPipeIndex; __le16 wRequests; __le16 wBlocks; /* rw if 0 */ - __le16 wMaxPacketSize; /* rw? */ - u8 bHSHubAddress; /* reserved: 0 */ - u8 bHSHubPort; /* ??? FIXME ??? */ + __le16 wMaxPacketSize; /* rw */ + union { + u8 dwa_bHSHubAddress; /* rw: DWA. */ + u8 hwa_bMaxBurst; /* rw: HWA. */ + }; + union { + u8 dwa_bHSHubPort; /* rw: DWA. */ + u8 hwa_bDeviceInfoIndex; /* rw: HWA. */ + }; u8 bSpeed; /* rw: xfer rate 'enum uwb_phy_rate' */ - u8 bDeviceAddress; /* rw: Target device address */ + union { + u8 dwa_bDeviceAddress; /* rw: DWA Target device address. */ + u8 hwa_reserved; /* rw: HWA. */ + }; u8 bEndpointAddress; /* rw: Target EP address */ u8 bDataSequence; /* ro: Current Data sequence */ __le32 dwCurrentWindow; /* ro */ diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index 4ce009324933..4db29859464f 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -23,6 +23,7 @@ struct user_namespace { struct uid_gid_map projid_map; atomic_t count; struct user_namespace *parent; + int level; kuid_t owner; kgid_t group; unsigned int proc_inum; diff --git a/include/linux/uwb/spec.h b/include/linux/uwb/spec.h index b52e44f1bd33..0df24bfcdb38 100644 --- a/include/linux/uwb/spec.h +++ b/include/linux/uwb/spec.h @@ -32,6 +32,7 @@ #include <linux/types.h> #include <linux/bitmap.h> +#include <linux/if_ether.h> #define i1480_FW 0x00000303 /* #define i1480_FW 0x00000302 */ @@ -130,7 +131,7 @@ enum { UWB_DRP_BACKOFF_WIN_MAX = 16 }; * it is also used to define headers sent down and up the wire/radio). */ struct uwb_mac_addr { - u8 data[6]; + u8 data[ETH_ALEN]; } __attribute__((packed)); @@ -568,7 +569,7 @@ struct uwb_rc_evt_confirm { /* Device Address Management event. [WHCI] section 3.1.3.2. */ struct uwb_rc_evt_dev_addr_mgmt { struct uwb_rceb rceb; - u8 baAddr[6]; + u8 baAddr[ETH_ALEN]; u8 bResultCode; } __attribute__((packed)); diff --git a/include/linux/vexpress.h b/include/linux/vexpress.h index 75818744ab59..617c01b8f74a 100644 --- a/include/linux/vexpress.h +++ b/include/linux/vexpress.h @@ -15,6 +15,7 @@ #define _LINUX_VEXPRESS_H #include <linux/device.h> +#include <linux/reboot.h> #define VEXPRESS_SITE_MB 0 #define VEXPRESS_SITE_DB1 1 @@ -115,9 +116,6 @@ unsigned __vexpress_get_site(struct device *dev, struct device_node *node); void vexpress_sysreg_early_init(void __iomem *base); void vexpress_sysreg_of_early_init(void); -void vexpress_power_off(void); -void vexpress_restart(char str, const char *cmd); - /* Clocks */ struct clk *vexpress_osc_setup(struct device *dev); diff --git a/include/linux/vfio.h b/include/linux/vfio.h index ab9e86224c54..24579a0312a0 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -45,6 +45,9 @@ extern int vfio_add_group_dev(struct device *dev, void *device_data); extern void *vfio_del_group_dev(struct device *dev); +extern struct vfio_device *vfio_device_get_from_dev(struct device *dev); +extern void vfio_device_put(struct vfio_device *device); +extern void *vfio_device_data(struct vfio_device *device); /** * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks @@ -87,4 +90,11 @@ extern void vfio_unregister_iommu_driver( TYPE tmp; \ offsetof(TYPE, MEMBER) + sizeof(tmp.MEMBER); }) \ +/* + * External user API + */ +extern struct vfio_group *vfio_group_get_external_user(struct file *filep); +extern void vfio_group_put_external_user(struct vfio_group *group); +extern int vfio_external_user_iommu_id(struct vfio_group *group); + #endif /* VFIO_H */ diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h index ddb419cf4530..502073a53dd3 100644 --- a/include/linux/vga_switcheroo.h +++ b/include/linux/vga_switcheroo.h @@ -45,7 +45,8 @@ struct vga_switcheroo_client_ops { #if defined(CONFIG_VGA_SWITCHEROO) void vga_switcheroo_unregister_client(struct pci_dev *dev); int vga_switcheroo_register_client(struct pci_dev *dev, - const struct vga_switcheroo_client_ops *ops); + const struct vga_switcheroo_client_ops *ops, + bool driver_power_control); int vga_switcheroo_register_audio_client(struct pci_dev *pdev, const struct vga_switcheroo_client_ops *ops, int id, bool active); @@ -60,11 +61,15 @@ int vga_switcheroo_process_delayed_switch(void); int vga_switcheroo_get_client_state(struct pci_dev *dev); +void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic); + +int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain); +int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain); #else static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {} static inline int vga_switcheroo_register_client(struct pci_dev *dev, - const struct vga_switcheroo_client_ops *ops) { return 0; } + const struct vga_switcheroo_client_ops *ops, bool driver_power_control) { return 0; } static inline void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) {} static inline int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) { return 0; } static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev, @@ -74,6 +79,10 @@ static inline void vga_switcheroo_unregister_handler(void) {} static inline int vga_switcheroo_process_delayed_switch(void) { return 0; } static inline int vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; } +static inline void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic) {} + +static inline int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain) { return -EINVAL; } +static inline int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain) { return -EINVAL; } #endif #endif /* _LINUX_VGA_SWITCHEROO_H_ */ diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h index 2c02f3a8d2ba..80cf8173a65b 100644 --- a/include/linux/vgaarb.h +++ b/include/linux/vgaarb.h @@ -65,8 +65,15 @@ struct pci_dev; * out of the arbitration process (and can be safe to take * interrupts at any time. */ +#if defined(CONFIG_VGA_ARB) extern void vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes); +#else +static inline void vga_set_legacy_decoding(struct pci_dev *pdev, + unsigned int decodes) +{ +} +#endif /** * vga_get - acquire & locks VGA resources diff --git a/include/linux/virtio.h b/include/linux/virtio.h index ff6714e6d0f5..36d36cc89329 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -8,6 +8,7 @@ #include <linux/device.h> #include <linux/mod_devicetable.h> #include <linux/gfp.h> +#include <linux/vringh.h> /** * virtqueue - a queue to register buffers for sending or receiving. @@ -33,10 +34,20 @@ struct virtqueue { void *priv; }; -int virtqueue_add_buf(struct virtqueue *vq, - struct scatterlist sg[], - unsigned int out_num, - unsigned int in_num, +int virtqueue_add_outbuf(struct virtqueue *vq, + struct scatterlist sg[], unsigned int num, + void *data, + gfp_t gfp); + +int virtqueue_add_inbuf(struct virtqueue *vq, + struct scatterlist sg[], unsigned int num, + void *data, + gfp_t gfp); + +int virtqueue_add_sgs(struct virtqueue *vq, + struct scatterlist *sgs[], + unsigned int out_sgs, + unsigned int in_sgs, void *data, gfp_t gfp); @@ -52,24 +63,23 @@ void virtqueue_disable_cb(struct virtqueue *vq); bool virtqueue_enable_cb(struct virtqueue *vq); +unsigned virtqueue_enable_cb_prepare(struct virtqueue *vq); + +bool virtqueue_poll(struct virtqueue *vq, unsigned); + bool virtqueue_enable_cb_delayed(struct virtqueue *vq); void *virtqueue_detach_unused_buf(struct virtqueue *vq); unsigned int virtqueue_get_vring_size(struct virtqueue *vq); -/* FIXME: Obsolete accessor, but required for virtio_net merge. */ -static inline unsigned int virtqueue_get_queue_index(struct virtqueue *vq) -{ - return vq->index; -} - /** * virtio_device - representation of a device using virtio * @index: unique position on the virtio bus * @dev: underlying device. * @id: the device type identification (used to match it with a driver). * @config: the configuration ops for this device. + * @vringh_config: configuration ops for host vrings. * @vqs: the list of virtqueues for this device. * @features: the features supported by both driver and device. * @priv: private pointer for the driver's use. @@ -79,6 +89,7 @@ struct virtio_device { struct device dev; struct virtio_device_id id; const struct virtio_config_ops *config; + const struct vringh_config_ops *vringh_config; struct list_head vqs; /* Note that this is a Linux set_bit-style bitmap. */ unsigned long features[1]; diff --git a/include/linux/virtio_caif.h b/include/linux/virtio_caif.h new file mode 100644 index 000000000000..5d2d3124ca3d --- /dev/null +++ b/include/linux/virtio_caif.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) ST-Ericsson AB 2012 + * Author: Sjur Brændeland <sjur.brandeland@stericsson.com> + * + * This header is BSD licensed so + * anyone can use the definitions to implement compatible remote processors + */ + +#ifndef VIRTIO_CAIF_H +#define VIRTIO_CAIF_H + +#include <linux/types.h> +struct virtio_caif_transf_config { + u16 headroom; + u16 tailroom; + u32 mtu; + u8 reserved[4]; +}; + +struct virtio_caif_config { + struct virtio_caif_transf_config uplink, downlink; + u8 reserved[8]; +}; +#endif diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index 63c6ea199519..b300787af8e0 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h @@ -1,9 +1,67 @@ #ifndef _LINUX_VIRTIO_RING_H #define _LINUX_VIRTIO_RING_H +#include <asm/barrier.h> #include <linux/irqreturn.h> #include <uapi/linux/virtio_ring.h> +/* + * Barriers in virtio are tricky. Non-SMP virtio guests can't assume + * they're not on an SMP host system, so they need to assume real + * barriers. Non-SMP virtio hosts could skip the barriers, but does + * anyone care? + * + * For virtio_pci on SMP, we don't need to order with respect to MMIO + * accesses through relaxed memory I/O windows, so smp_mb() et al are + * sufficient. + * + * For using virtio to talk to real devices (eg. other heterogeneous + * CPUs) we do need real barriers. In theory, we could be using both + * kinds of virtio, so it's a runtime decision, and the branch is + * actually quite cheap. + */ + +#ifdef CONFIG_SMP +static inline void virtio_mb(bool weak_barriers) +{ + if (weak_barriers) + smp_mb(); + else + mb(); +} + +static inline void virtio_rmb(bool weak_barriers) +{ + if (weak_barriers) + smp_rmb(); + else + rmb(); +} + +static inline void virtio_wmb(bool weak_barriers) +{ + if (weak_barriers) + smp_wmb(); + else + wmb(); +} +#else +static inline void virtio_mb(bool weak_barriers) +{ + mb(); +} + +static inline void virtio_rmb(bool weak_barriers) +{ + rmb(); +} + +static inline void virtio_wmb(bool weak_barriers) +{ + wmb(); +} +#endif + struct virtio_device; struct virtqueue; diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h index bd6cf61142be..1855f0a22add 100644 --- a/include/linux/vm_event_item.h +++ b/include/linux/vm_event_item.h @@ -70,6 +70,12 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, THP_ZERO_PAGE_ALLOC, THP_ZERO_PAGE_ALLOC_FAILED, #endif +#ifdef CONFIG_SMP + NR_TLB_REMOTE_FLUSH, /* cpu tried to flush others' tlbs */ + NR_TLB_REMOTE_FLUSH_RECEIVED,/* cpu received ipi for flush */ +#endif + NR_TLB_LOCAL_FLUSH_ALL, + NR_TLB_LOCAL_FLUSH_ONE, NR_VM_EVENT_ITEMS }; diff --git a/include/linux/vm_sockets.h b/include/linux/vm_sockets.h new file mode 100644 index 000000000000..0805eecba8f7 --- /dev/null +++ b/include/linux/vm_sockets.h @@ -0,0 +1,23 @@ +/* + * VMware vSockets Driver + * + * Copyright (C) 2007-2013 VMware, Inc. All rights reserved. + * + * 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 and no later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef _VM_SOCKETS_H +#define _VM_SOCKETS_H + +#include <uapi/linux/vm_sockets.h> + +int vm_sockets_get_local_cid(void); + +#endif /* _VM_SOCKETS_H */ diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 6071e911c7f4..4b8a89189a29 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -3,17 +3,19 @@ #include <linux/spinlock.h> #include <linux/init.h> +#include <linux/list.h> #include <asm/page.h> /* pgprot_t */ +#include <linux/rbtree.h> struct vm_area_struct; /* vma defining user mapping in mm_types.h */ /* bits in flags of vmalloc's vm_struct below */ -#define VM_IOREMAP 0x00000001 /* ioremap() and friends */ -#define VM_ALLOC 0x00000002 /* vmalloc() */ -#define VM_MAP 0x00000004 /* vmap()ed pages */ -#define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */ -#define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */ -#define VM_UNLIST 0x00000020 /* vm_struct is not listed in vmlist */ +#define VM_IOREMAP 0x00000001 /* ioremap() and friends */ +#define VM_ALLOC 0x00000002 /* vmalloc() */ +#define VM_MAP 0x00000004 /* vmap()ed pages */ +#define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */ +#define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */ +#define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */ /* bits [20..32] reserved for arch specific ioremap internals */ /* @@ -35,6 +37,17 @@ struct vm_struct { const void *caller; }; +struct vmap_area { + unsigned long va_start; + unsigned long va_end; + unsigned long flags; + struct rb_node rb_node; /* address sorted rbtree */ + struct list_head list; /* address sorted list */ + struct list_head purge_list; /* "lazy purge" list */ + struct vm_struct *vm; + struct rcu_head rcu_head; +}; + /* * Highlevel APIs for driver use */ @@ -69,6 +82,10 @@ extern void *vmap(struct page **pages, unsigned int count, unsigned long flags, pgprot_t prot); extern void vunmap(const void *addr); +extern int remap_vmalloc_range_partial(struct vm_area_struct *vma, + unsigned long uaddr, void *kaddr, + unsigned long size); + extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, unsigned long pgoff); void vmalloc_sync_all(void); @@ -130,8 +147,7 @@ extern long vwrite(char *buf, char *addr, unsigned long count); /* * Internals. Dont't use.. */ -extern rwlock_t vmlist_lock; -extern struct vm_struct *vmlist; +extern struct list_head vmap_area_list; extern __init void vm_area_add_early(struct vm_struct *vm); extern __init void vm_area_register_early(struct vm_struct *vm, size_t align); @@ -158,4 +174,22 @@ pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms) # endif #endif +struct vmalloc_info { + unsigned long used; + unsigned long largest_chunk; +}; + +#ifdef CONFIG_MMU +#define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START) +extern void get_vmalloc_info(struct vmalloc_info *vmi); +#else + +#define VMALLOC_TOTAL 0UL +#define get_vmalloc_info(vmi) \ +do { \ + (vmi)->used = 0; \ + (vmi)->largest_chunk = 0; \ +} while (0) +#endif + #endif /* _LINUX_VMALLOC_H */ diff --git a/include/linux/vmpressure.h b/include/linux/vmpressure.h new file mode 100644 index 000000000000..3f3788d49362 --- /dev/null +++ b/include/linux/vmpressure.h @@ -0,0 +1,50 @@ +#ifndef __LINUX_VMPRESSURE_H +#define __LINUX_VMPRESSURE_H + +#include <linux/mutex.h> +#include <linux/list.h> +#include <linux/workqueue.h> +#include <linux/gfp.h> +#include <linux/types.h> +#include <linux/cgroup.h> + +struct vmpressure { + unsigned long scanned; + unsigned long reclaimed; + /* The lock is used to keep the scanned/reclaimed above in sync. */ + struct spinlock sr_lock; + + /* The list of vmpressure_event structs. */ + struct list_head events; + /* Have to grab the lock on events traversal or modifications. */ + struct mutex events_lock; + + struct work_struct work; +}; + +struct mem_cgroup; + +#ifdef CONFIG_MEMCG +extern void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, + unsigned long scanned, unsigned long reclaimed); +extern void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio); + +extern void vmpressure_init(struct vmpressure *vmpr); +extern void vmpressure_cleanup(struct vmpressure *vmpr); +extern struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg); +extern struct cgroup_subsys_state *vmpressure_to_css(struct vmpressure *vmpr); +extern struct vmpressure *css_to_vmpressure(struct cgroup_subsys_state *css); +extern int vmpressure_register_event(struct cgroup_subsys_state *css, + struct cftype *cft, + struct eventfd_ctx *eventfd, + const char *args); +extern void vmpressure_unregister_event(struct cgroup_subsys_state *css, + struct cftype *cft, + struct eventfd_ctx *eventfd); +#else +static inline void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, + unsigned long scanned, unsigned long reclaimed) {} +static inline void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, + int prio) {} +#endif /* CONFIG_MEMCG */ +#endif /* __LINUX_VMPRESSURE_H */ diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 5fd71a7d0dfd..e4b948080d20 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -48,13 +48,8 @@ static inline void count_vm_events(enum vm_event_item item, long delta) } extern void all_vm_events(unsigned long *); -#ifdef CONFIG_HOTPLUG + extern void vm_events_fold_cpu(int cpu); -#else -static inline void vm_events_fold_cpu(int cpu) -{ -} -#endif #else @@ -148,7 +143,6 @@ static inline unsigned long zone_page_state_snapshot(struct zone *zone, } extern unsigned long global_reclaimable_pages(void); -extern unsigned long zone_reclaimable_pages(struct zone *zone); #ifdef CONFIG_NUMA /* @@ -203,7 +197,7 @@ extern void __inc_zone_state(struct zone *, enum zone_stat_item); extern void dec_zone_state(struct zone *, enum zone_stat_item); extern void __dec_zone_state(struct zone *, enum zone_stat_item); -void refresh_cpu_vm_stats(int); +void cpu_vm_stats_fold(int cpu); void refresh_zone_stat_thresholds(void); void drain_zonestat(struct zone *zone, struct per_cpu_pageset *); @@ -260,6 +254,7 @@ static inline void __dec_zone_page_state(struct page *page, static inline void refresh_cpu_vm_stats(int cpu) { } static inline void refresh_zone_stat_thresholds(void) { } +static inline void cpu_vm_stats_fold(int cpu) { } static inline void drain_zonestat(struct zone *zone, struct per_cpu_pageset *pset) { } diff --git a/include/linux/vringh.h b/include/linux/vringh.h new file mode 100644 index 000000000000..749cde28728b --- /dev/null +++ b/include/linux/vringh.h @@ -0,0 +1,225 @@ +/* + * Linux host-side vring helpers; for when the kernel needs to access + * someone else's vring. + * + * Copyright IBM Corporation, 2013. + * Parts taken from drivers/vhost/vhost.c Copyright 2009 Red Hat, Inc. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Written by: Rusty Russell <rusty@rustcorp.com.au> + */ +#ifndef _LINUX_VRINGH_H +#define _LINUX_VRINGH_H +#include <uapi/linux/virtio_ring.h> +#include <linux/uio.h> +#include <linux/slab.h> +#include <asm/barrier.h> + +/* virtio_ring with information needed for host access. */ +struct vringh { + /* Guest publishes used event idx (note: we always do). */ + bool event_indices; + + /* Can we get away with weak barriers? */ + bool weak_barriers; + + /* Last available index we saw (ie. where we're up to). */ + u16 last_avail_idx; + + /* Last index we used. */ + u16 last_used_idx; + + /* How many descriptors we've completed since last need_notify(). */ + u32 completed; + + /* The vring (note: it may contain user pointers!) */ + struct vring vring; + + /* The function to call to notify the guest about added buffers */ + void (*notify)(struct vringh *); +}; + +/** + * struct vringh_config_ops - ops for creating a host vring from a virtio driver + * @find_vrhs: find the host vrings and instantiate them + * vdev: the virtio_device + * nhvrs: the number of host vrings to find + * hvrs: on success, includes new host vrings + * callbacks: array of driver callbacks, for each host vring + * include a NULL entry for vqs that do not need a callback + * Returns 0 on success or error status + * @del_vrhs: free the host vrings found by find_vrhs(). + */ +struct virtio_device; +typedef void vrh_callback_t(struct virtio_device *, struct vringh *); +struct vringh_config_ops { + int (*find_vrhs)(struct virtio_device *vdev, unsigned nhvrs, + struct vringh *vrhs[], vrh_callback_t *callbacks[]); + void (*del_vrhs)(struct virtio_device *vdev); +}; + +/* The memory the vring can access, and what offset to apply. */ +struct vringh_range { + u64 start, end_incl; + u64 offset; +}; + +/** + * struct vringh_iov - iovec mangler. + * + * Mangles iovec in place, and restores it. + * Remaining data is iov + i, of used - i elements. + */ +struct vringh_iov { + struct iovec *iov; + size_t consumed; /* Within iov[i] */ + unsigned i, used, max_num; +}; + +/** + * struct vringh_iov - kvec mangler. + * + * Mangles kvec in place, and restores it. + * Remaining data is iov + i, of used - i elements. + */ +struct vringh_kiov { + struct kvec *iov; + size_t consumed; /* Within iov[i] */ + unsigned i, used, max_num; +}; + +/* Flag on max_num to indicate we're kmalloced. */ +#define VRINGH_IOV_ALLOCATED 0x8000000 + +/* Helpers for userspace vrings. */ +int vringh_init_user(struct vringh *vrh, u32 features, + unsigned int num, bool weak_barriers, + struct vring_desc __user *desc, + struct vring_avail __user *avail, + struct vring_used __user *used); + +static inline void vringh_iov_init(struct vringh_iov *iov, + struct iovec *iovec, unsigned num) +{ + iov->used = iov->i = 0; + iov->consumed = 0; + iov->max_num = num; + iov->iov = iovec; +} + +static inline void vringh_iov_reset(struct vringh_iov *iov) +{ + iov->iov[iov->i].iov_len += iov->consumed; + iov->iov[iov->i].iov_base -= iov->consumed; + iov->consumed = 0; + iov->i = 0; +} + +static inline void vringh_iov_cleanup(struct vringh_iov *iov) +{ + if (iov->max_num & VRINGH_IOV_ALLOCATED) + kfree(iov->iov); + iov->max_num = iov->used = iov->i = iov->consumed = 0; + iov->iov = NULL; +} + +/* Convert a descriptor into iovecs. */ +int vringh_getdesc_user(struct vringh *vrh, + struct vringh_iov *riov, + struct vringh_iov *wiov, + bool (*getrange)(struct vringh *vrh, + u64 addr, struct vringh_range *r), + u16 *head); + +/* Copy bytes from readable vsg, consuming it (and incrementing wiov->i). */ +ssize_t vringh_iov_pull_user(struct vringh_iov *riov, void *dst, size_t len); + +/* Copy bytes into writable vsg, consuming it (and incrementing wiov->i). */ +ssize_t vringh_iov_push_user(struct vringh_iov *wiov, + const void *src, size_t len); + +/* Mark a descriptor as used. */ +int vringh_complete_user(struct vringh *vrh, u16 head, u32 len); +int vringh_complete_multi_user(struct vringh *vrh, + const struct vring_used_elem used[], + unsigned num_used); + +/* Pretend we've never seen descriptor (for easy error handling). */ +void vringh_abandon_user(struct vringh *vrh, unsigned int num); + +/* Do we need to fire the eventfd to notify the other side? */ +int vringh_need_notify_user(struct vringh *vrh); + +bool vringh_notify_enable_user(struct vringh *vrh); +void vringh_notify_disable_user(struct vringh *vrh); + +/* Helpers for kernelspace vrings. */ +int vringh_init_kern(struct vringh *vrh, u32 features, + unsigned int num, bool weak_barriers, + struct vring_desc *desc, + struct vring_avail *avail, + struct vring_used *used); + +static inline void vringh_kiov_init(struct vringh_kiov *kiov, + struct kvec *kvec, unsigned num) +{ + kiov->used = kiov->i = 0; + kiov->consumed = 0; + kiov->max_num = num; + kiov->iov = kvec; +} + +static inline void vringh_kiov_reset(struct vringh_kiov *kiov) +{ + kiov->iov[kiov->i].iov_len += kiov->consumed; + kiov->iov[kiov->i].iov_base -= kiov->consumed; + kiov->consumed = 0; + kiov->i = 0; +} + +static inline void vringh_kiov_cleanup(struct vringh_kiov *kiov) +{ + if (kiov->max_num & VRINGH_IOV_ALLOCATED) + kfree(kiov->iov); + kiov->max_num = kiov->used = kiov->i = kiov->consumed = 0; + kiov->iov = NULL; +} + +int vringh_getdesc_kern(struct vringh *vrh, + struct vringh_kiov *riov, + struct vringh_kiov *wiov, + u16 *head, + gfp_t gfp); + +ssize_t vringh_iov_pull_kern(struct vringh_kiov *riov, void *dst, size_t len); +ssize_t vringh_iov_push_kern(struct vringh_kiov *wiov, + const void *src, size_t len); +void vringh_abandon_kern(struct vringh *vrh, unsigned int num); +int vringh_complete_kern(struct vringh *vrh, u16 head, u32 len); + +bool vringh_notify_enable_kern(struct vringh *vrh); +void vringh_notify_disable_kern(struct vringh *vrh); + +int vringh_need_notify_kern(struct vringh *vrh); + +/* Notify the guest about buffers added to the used ring */ +static inline void vringh_notify(struct vringh *vrh) +{ + if (vrh->notify) + vrh->notify(vrh); +} + +#endif /* _LINUX_VRINGH_H */ diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index e8d65718560b..8d7634247fb4 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -36,7 +36,7 @@ extern int fg_console, last_console, want_console; int vc_allocate(unsigned int console); int vc_cons_allocated(unsigned int console); int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines); -void vc_deallocate(unsigned int console); +struct vc_data *vc_deallocate(unsigned int console); void reset_palette(struct vc_data *vc); void do_blank_screen(int entering_gfx); void do_unblank_screen(int leaving_gfx); @@ -133,8 +133,6 @@ void change_console(struct vc_data *new_vc); void reset_vc(struct vc_data *vc); extern int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt); -extern int unbind_con_driver(const struct consw *csw, int first, int last, - int deflt); int vty_init(const struct file_operations *console_fops); static inline bool vt_force_oops_output(struct vc_data *vc) diff --git a/include/linux/vtime.h b/include/linux/vtime.h index 71a5782d8c59..f5b72b364bda 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h @@ -1,18 +1,68 @@ #ifndef _LINUX_KERNEL_VTIME_H #define _LINUX_KERNEL_VTIME_H +#include <linux/context_tracking_state.h> +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE +#include <asm/vtime.h> +#endif + + struct task_struct; +/* + * vtime_accounting_enabled() definitions/declarations + */ +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE +static inline bool vtime_accounting_enabled(void) { return true; } +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ + +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN +static inline bool vtime_accounting_enabled(void) +{ + if (static_key_false(&context_tracking_enabled)) { + if (context_tracking_active()) + return true; + } + + return false; +} +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */ + +#ifndef CONFIG_VIRT_CPU_ACCOUNTING +static inline bool vtime_accounting_enabled(void) { return false; } +#endif /* !CONFIG_VIRT_CPU_ACCOUNTING */ + + +/* + * Common vtime APIs + */ #ifdef CONFIG_VIRT_CPU_ACCOUNTING + +#ifdef __ARCH_HAS_VTIME_TASK_SWITCH extern void vtime_task_switch(struct task_struct *prev); +#else +extern void vtime_common_task_switch(struct task_struct *prev); +static inline void vtime_task_switch(struct task_struct *prev) +{ + if (vtime_accounting_enabled()) + vtime_common_task_switch(prev); +} +#endif /* __ARCH_HAS_VTIME_TASK_SWITCH */ + extern void vtime_account_system(struct task_struct *tsk); extern void vtime_account_idle(struct task_struct *tsk); extern void vtime_account_user(struct task_struct *tsk); -extern void vtime_account_irq_enter(struct task_struct *tsk); -#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE -static inline bool vtime_accounting_enabled(void) { return true; } -#endif +#ifdef __ARCH_HAS_VTIME_ACCOUNT +extern void vtime_account_irq_enter(struct task_struct *tsk); +#else +extern void vtime_common_account_irq_enter(struct task_struct *tsk); +static inline void vtime_account_irq_enter(struct task_struct *tsk) +{ + if (vtime_accounting_enabled()) + vtime_common_account_irq_enter(tsk); +} +#endif /* __ARCH_HAS_VTIME_ACCOUNT */ #else /* !CONFIG_VIRT_CPU_ACCOUNTING */ @@ -20,22 +70,28 @@ static inline void vtime_task_switch(struct task_struct *prev) { } static inline void vtime_account_system(struct task_struct *tsk) { } static inline void vtime_account_user(struct task_struct *tsk) { } static inline void vtime_account_irq_enter(struct task_struct *tsk) { } -static inline bool vtime_accounting_enabled(void) { return false; } -#endif +#endif /* !CONFIG_VIRT_CPU_ACCOUNTING */ #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN extern void arch_vtime_task_switch(struct task_struct *tsk); -extern void vtime_account_irq_exit(struct task_struct *tsk); -extern bool vtime_accounting_enabled(void); +extern void vtime_gen_account_irq_exit(struct task_struct *tsk); + +static inline void vtime_account_irq_exit(struct task_struct *tsk) +{ + if (vtime_accounting_enabled()) + vtime_gen_account_irq_exit(tsk); +} + extern void vtime_user_enter(struct task_struct *tsk); + static inline void vtime_user_exit(struct task_struct *tsk) { vtime_account_user(tsk); } extern void vtime_guest_enter(struct task_struct *tsk); extern void vtime_guest_exit(struct task_struct *tsk); -extern void vtime_init_idle(struct task_struct *tsk); -#else +extern void vtime_init_idle(struct task_struct *tsk, int cpu); +#else /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN */ static inline void vtime_account_irq_exit(struct task_struct *tsk) { /* On hard|softirq exit we always account to hard|softirq cputime */ @@ -45,7 +101,7 @@ static inline void vtime_user_enter(struct task_struct *tsk) { } static inline void vtime_user_exit(struct task_struct *tsk) { } static inline void vtime_guest_enter(struct task_struct *tsk) { } static inline void vtime_guest_exit(struct task_struct *tsk) { } -static inline void vtime_init_idle(struct task_struct *tsk) { } +static inline void vtime_init_idle(struct task_struct *tsk, int cpu) { } #endif #ifdef CONFIG_IRQ_TIME_ACCOUNTING diff --git a/include/linux/wait.h b/include/linux/wait.h index 7cb64d4b499d..a67fc1635592 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -23,6 +23,7 @@ struct __wait_queue { struct wait_bit_key { void *flags; int bit_nr; +#define WAIT_ATOMIC_T_BIT_NR -1 }; struct wait_bit_queue { @@ -60,6 +61,9 @@ struct task_struct; #define __WAIT_BIT_KEY_INITIALIZER(word, bit) \ { .flags = word, .bit_nr = bit, } +#define __WAIT_ATOMIC_T_KEY_INITIALIZER(p) \ + { .flags = p, .bit_nr = WAIT_ATOMIC_T_BIT_NR, } + extern void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *); #define init_waitqueue_head(q) \ @@ -146,8 +150,10 @@ void __wake_up_bit(wait_queue_head_t *, void *, int); int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); void wake_up_bit(void *, int); +void wake_up_atomic_t(atomic_t *); int out_of_line_wait_on_bit(void *, int, int (*)(void *), unsigned); int out_of_line_wait_on_bit_lock(void *, int, int (*)(void *), unsigned); +int out_of_line_wait_on_atomic_t(atomic_t *, int (*)(atomic_t *), unsigned); wait_queue_head_t *bit_waitqueue(void *, int); #define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL) @@ -217,6 +223,8 @@ do { \ if (!ret) \ break; \ } \ + if (!ret && (condition)) \ + ret = 1; \ finish_wait(&wq, &__wait); \ } while (0) @@ -233,8 +241,9 @@ do { \ * wake_up() has to be called after changing any variable that could * change the result of the wait condition. * - * The function returns 0 if the @timeout elapsed, and the remaining - * jiffies if the condition evaluated to true before the timeout elapsed. + * The function returns 0 if the @timeout elapsed, or the remaining + * jiffies (at least 1) if the @condition evaluated to %true before + * the @timeout elapsed. */ #define wait_event_timeout(wq, condition, timeout) \ ({ \ @@ -302,6 +311,8 @@ do { \ ret = -ERESTARTSYS; \ break; \ } \ + if (!ret && (condition)) \ + ret = 1; \ finish_wait(&wq, &__wait); \ } while (0) @@ -318,9 +329,10 @@ do { \ * wake_up() has to be called after changing any variable that could * change the result of the wait condition. * - * The function returns 0 if the @timeout elapsed, -ERESTARTSYS if it - * was interrupted by a signal, and the remaining jiffies otherwise - * if the condition evaluated to true before the timeout elapsed. + * Returns: + * 0 if the @timeout elapsed, -%ERESTARTSYS if it was interrupted by + * a signal, or the remaining jiffies (at least 1) if the @condition + * evaluated to %true before the @timeout elapsed. */ #define wait_event_interruptible_timeout(wq, condition, timeout) \ ({ \ @@ -330,6 +342,92 @@ do { \ __ret; \ }) +#define __wait_event_hrtimeout(wq, condition, timeout, state) \ +({ \ + int __ret = 0; \ + DEFINE_WAIT(__wait); \ + struct hrtimer_sleeper __t; \ + \ + hrtimer_init_on_stack(&__t.timer, CLOCK_MONOTONIC, \ + HRTIMER_MODE_REL); \ + hrtimer_init_sleeper(&__t, current); \ + if ((timeout).tv64 != KTIME_MAX) \ + hrtimer_start_range_ns(&__t.timer, timeout, \ + current->timer_slack_ns, \ + HRTIMER_MODE_REL); \ + \ + for (;;) { \ + prepare_to_wait(&wq, &__wait, state); \ + if (condition) \ + break; \ + if (state == TASK_INTERRUPTIBLE && \ + signal_pending(current)) { \ + __ret = -ERESTARTSYS; \ + break; \ + } \ + if (!__t.task) { \ + __ret = -ETIME; \ + break; \ + } \ + schedule(); \ + } \ + \ + hrtimer_cancel(&__t.timer); \ + destroy_hrtimer_on_stack(&__t.timer); \ + finish_wait(&wq, &__wait); \ + __ret; \ +}) + +/** + * wait_event_hrtimeout - sleep until a condition gets true or a timeout elapses + * @wq: the waitqueue to wait on + * @condition: a C expression for the event to wait for + * @timeout: timeout, as a ktime_t + * + * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the + * @condition evaluates to true or a signal is received. + * The @condition is checked each time the waitqueue @wq is woken up. + * + * wake_up() has to be called after changing any variable that could + * change the result of the wait condition. + * + * The function returns 0 if @condition became true, or -ETIME if the timeout + * elapsed. + */ +#define wait_event_hrtimeout(wq, condition, timeout) \ +({ \ + int __ret = 0; \ + if (!(condition)) \ + __ret = __wait_event_hrtimeout(wq, condition, timeout, \ + TASK_UNINTERRUPTIBLE); \ + __ret; \ +}) + +/** + * wait_event_interruptible_hrtimeout - sleep until a condition gets true or a timeout elapses + * @wq: the waitqueue to wait on + * @condition: a C expression for the event to wait for + * @timeout: timeout, as a ktime_t + * + * The process is put to sleep (TASK_INTERRUPTIBLE) until the + * @condition evaluates to true or a signal is received. + * The @condition is checked each time the waitqueue @wq is woken up. + * + * wake_up() has to be called after changing any variable that could + * change the result of the wait condition. + * + * The function returns 0 if @condition became true, -ERESTARTSYS if it was + * interrupted by a signal, or -ETIME if the timeout elapsed. + */ +#define wait_event_interruptible_hrtimeout(wq, condition, timeout) \ +({ \ + long __ret = 0; \ + if (!(condition)) \ + __ret = __wait_event_hrtimeout(wq, condition, timeout, \ + TASK_INTERRUPTIBLE); \ + __ret; \ +}) + #define __wait_event_interruptible_exclusive(wq, condition, ret) \ do { \ DEFINE_WAIT(__wait); \ @@ -713,6 +811,63 @@ do { \ __ret; \ }) +#define __wait_event_interruptible_lock_irq_timeout(wq, condition, \ + lock, ret) \ +do { \ + DEFINE_WAIT(__wait); \ + \ + for (;;) { \ + prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (signal_pending(current)) { \ + ret = -ERESTARTSYS; \ + break; \ + } \ + spin_unlock_irq(&lock); \ + ret = schedule_timeout(ret); \ + spin_lock_irq(&lock); \ + if (!ret) \ + break; \ + } \ + finish_wait(&wq, &__wait); \ +} while (0) + +/** + * wait_event_interruptible_lock_irq_timeout - sleep until a condition gets true or a timeout elapses. + * The condition is checked under the lock. This is expected + * to be called with the lock taken. + * @wq: the waitqueue to wait on + * @condition: a C expression for the event to wait for + * @lock: a locked spinlock_t, which will be released before schedule() + * and reacquired afterwards. + * @timeout: timeout, in jiffies + * + * The process is put to sleep (TASK_INTERRUPTIBLE) until the + * @condition evaluates to true or signal is received. The @condition is + * checked each time the waitqueue @wq is woken up. + * + * wake_up() has to be called after changing any variable that could + * change the result of the wait condition. + * + * This is supposed to be called while holding the lock. The lock is + * dropped before going to sleep and is reacquired afterwards. + * + * The function returns 0 if the @timeout elapsed, -ERESTARTSYS if it + * was interrupted by a signal, and the remaining jiffies otherwise + * if the condition evaluated to true before the timeout elapsed. + */ +#define wait_event_interruptible_lock_irq_timeout(wq, condition, lock, \ + timeout) \ +({ \ + int __ret = timeout; \ + \ + if (!(condition)) \ + __wait_event_interruptible_lock_irq_timeout( \ + wq, condition, lock, __ret); \ + __ret; \ +}) + /* * These are the old interfaces to sleep waiting for an event. @@ -810,5 +965,23 @@ static inline int wait_on_bit_lock(void *word, int bit, return 0; return out_of_line_wait_on_bit_lock(word, bit, action, mode); } + +/** + * wait_on_atomic_t - Wait for an atomic_t to become 0 + * @val: The atomic value being waited on, a kernel virtual address + * @action: the function used to sleep, which may take special actions + * @mode: the task state to sleep in + * + * Wait for an atomic_t to become 0. We abuse the bit-wait waitqueue table for + * the purpose of getting a waitqueue, but we set the key to a bit number + * outside of the target 'word'. + */ +static inline +int wait_on_atomic_t(atomic_t *val, int (*action)(atomic_t *), unsigned mode) +{ + if (atomic_read(val) == 0) + return 0; + return out_of_line_wait_on_atomic_t(val, action, mode); +} #endif diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 8afab27cdbc2..594521ba0d43 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -11,6 +11,7 @@ #include <linux/lockdep.h> #include <linux/threads.h> #include <linux/atomic.h> +#include <linux/cpumask.h> struct workqueue_struct; @@ -68,7 +69,7 @@ enum { WORK_STRUCT_COLOR_BITS, /* data contains off-queue information when !WORK_STRUCT_PWQ */ - WORK_OFFQ_FLAG_BASE = WORK_STRUCT_FLAG_BITS, + WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT, WORK_OFFQ_CANCELING = (1 << WORK_OFFQ_FLAG_BASE), @@ -91,6 +92,9 @@ enum { /* bit mask for work_busy() return values */ WORK_BUSY_PENDING = 1 << 0, WORK_BUSY_RUNNING = 1 << 1, + + /* maximum string length for set_worker_desc() */ + WORKER_DESC_LEN = 24, }; struct work_struct { @@ -115,6 +119,20 @@ struct delayed_work { int cpu; }; +/* + * A struct for workqueue attributes. This can be used to change + * attributes of an unbound workqueue. + * + * Unlike other fields, ->no_numa isn't a property of a worker_pool. It + * only modifies how apply_workqueue_attrs() select pools and thus doesn't + * participate in pool hash calculations or equality comparisons. + */ +struct workqueue_attrs { + int nice; /* nice level */ + cpumask_var_t cpumask; /* allowed CPUs */ + bool no_numa; /* disable NUMA affinity */ +}; + static inline struct delayed_work *to_delayed_work(struct work_struct *work) { return container_of(work, struct delayed_work, work); @@ -277,15 +295,48 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } * Documentation/workqueue.txt. */ enum { - WQ_NON_REENTRANT = 1 << 0, /* guarantee non-reentrance */ + /* + * All wqs are now non-reentrant making the following flag + * meaningless. Will be removed. + */ + WQ_NON_REENTRANT = 1 << 0, /* DEPRECATED */ + WQ_UNBOUND = 1 << 1, /* not bound to any cpu */ WQ_FREEZABLE = 1 << 2, /* freeze during suspend */ WQ_MEM_RECLAIM = 1 << 3, /* may be used for memory reclaim */ WQ_HIGHPRI = 1 << 4, /* high priority */ WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ + WQ_SYSFS = 1 << 6, /* visible in sysfs, see wq_sysfs_register() */ - WQ_DRAINING = 1 << 6, /* internal: workqueue is draining */ - WQ_RESCUER = 1 << 7, /* internal: workqueue has rescuer */ + /* + * Per-cpu workqueues are generally preferred because they tend to + * show better performance thanks to cache locality. Per-cpu + * workqueues exclude the scheduler from choosing the CPU to + * execute the worker threads, which has an unfortunate side effect + * of increasing power consumption. + * + * The scheduler considers a CPU idle if it doesn't have any task + * to execute and tries to keep idle cores idle to conserve power; + * however, for example, a per-cpu work item scheduled from an + * interrupt handler on an idle CPU will force the scheduler to + * excute the work item on that CPU breaking the idleness, which in + * turn may lead to more scheduling choices which are sub-optimal + * in terms of power consumption. + * + * Workqueues marked with WQ_POWER_EFFICIENT are per-cpu by default + * but become unbound if workqueue.power_efficient kernel param is + * specified. Per-cpu workqueues which are identified to + * contribute significantly to power-consumption are identified and + * marked with this flag and enabling the power_efficient mode + * leads to noticeable power saving at the cost of small + * performance disadvantage. + * + * http://thread.gmane.org/gmane.linux.kernel/1480396 + */ + WQ_POWER_EFFICIENT = 1 << 7, + + __WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */ + __WQ_ORDERED = 1 << 17, /* internal: workqueue is ordered */ WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */ WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */ @@ -314,11 +365,19 @@ enum { * * system_freezable_wq is equivalent to system_wq except that it's * freezable. + * + * *_power_efficient_wq are inclined towards saving power and converted + * into WQ_UNBOUND variants if 'wq_power_efficient' is enabled; otherwise, + * they are same as their non-power-efficient counterparts - e.g. + * system_power_efficient_wq is identical to system_wq if + * 'wq_power_efficient' is disabled. See WQ_POWER_EFFICIENT for more info. */ extern struct workqueue_struct *system_wq; extern struct workqueue_struct *system_long_wq; extern struct workqueue_struct *system_unbound_wq; extern struct workqueue_struct *system_freezable_wq; +extern struct workqueue_struct *system_power_efficient_wq; +extern struct workqueue_struct *system_freezable_power_efficient_wq; static inline struct workqueue_struct * __deprecated __system_nrt_wq(void) { @@ -388,41 +447,35 @@ __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active, * Pointer to the allocated workqueue on success, %NULL on failure. */ #define alloc_ordered_workqueue(fmt, flags, args...) \ - alloc_workqueue(fmt, WQ_UNBOUND | (flags), 1, ##args) + alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags), 1, ##args) #define create_workqueue(name) \ - alloc_workqueue((name), WQ_MEM_RECLAIM, 1) + alloc_workqueue("%s", WQ_MEM_RECLAIM, 1, (name)) #define create_freezable_workqueue(name) \ - alloc_workqueue((name), WQ_FREEZABLE | WQ_UNBOUND | WQ_MEM_RECLAIM, 1) + alloc_workqueue("%s", WQ_FREEZABLE | WQ_UNBOUND | WQ_MEM_RECLAIM, \ + 1, (name)) #define create_singlethread_workqueue(name) \ - alloc_workqueue((name), WQ_UNBOUND | WQ_MEM_RECLAIM, 1) + alloc_workqueue("%s", WQ_UNBOUND | WQ_MEM_RECLAIM, 1, (name)) extern void destroy_workqueue(struct workqueue_struct *wq); +struct workqueue_attrs *alloc_workqueue_attrs(gfp_t gfp_mask); +void free_workqueue_attrs(struct workqueue_attrs *attrs); +int apply_workqueue_attrs(struct workqueue_struct *wq, + const struct workqueue_attrs *attrs); + extern bool queue_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work); -extern bool queue_work(struct workqueue_struct *wq, struct work_struct *work); extern bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay); -extern bool queue_delayed_work(struct workqueue_struct *wq, - struct delayed_work *work, unsigned long delay); extern bool mod_delayed_work_on(int cpu, struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay); -extern bool mod_delayed_work(struct workqueue_struct *wq, - struct delayed_work *dwork, unsigned long delay); extern void flush_workqueue(struct workqueue_struct *wq); extern void drain_workqueue(struct workqueue_struct *wq); extern void flush_scheduled_work(void); -extern bool schedule_work_on(int cpu, struct work_struct *work); -extern bool schedule_work(struct work_struct *work); -extern bool schedule_delayed_work_on(int cpu, struct delayed_work *work, - unsigned long delay); -extern bool schedule_delayed_work(struct delayed_work *work, - unsigned long delay); extern int schedule_on_each_cpu(work_func_t func); -extern int keventd_up(void); int execute_in_process_context(work_func_t fn, struct execute_work *); @@ -435,8 +488,122 @@ extern bool cancel_delayed_work_sync(struct delayed_work *dwork); extern void workqueue_set_max_active(struct workqueue_struct *wq, int max_active); -extern bool workqueue_congested(unsigned int cpu, struct workqueue_struct *wq); +extern bool current_is_workqueue_rescuer(void); +extern bool workqueue_congested(int cpu, struct workqueue_struct *wq); extern unsigned int work_busy(struct work_struct *work); +extern __printf(1, 2) void set_worker_desc(const char *fmt, ...); +extern void print_worker_info(const char *log_lvl, struct task_struct *task); + +/** + * queue_work - queue work on a workqueue + * @wq: workqueue to use + * @work: work to queue + * + * Returns %false if @work was already on a queue, %true otherwise. + * + * We queue the work to the CPU on which it was submitted, but if the CPU dies + * it can be processed by another CPU. + */ +static inline bool queue_work(struct workqueue_struct *wq, + struct work_struct *work) +{ + return queue_work_on(WORK_CPU_UNBOUND, wq, work); +} + +/** + * queue_delayed_work - queue work on a workqueue after delay + * @wq: workqueue to use + * @dwork: delayable work to queue + * @delay: number of jiffies to wait before queueing + * + * Equivalent to queue_delayed_work_on() but tries to use the local CPU. + */ +static inline bool queue_delayed_work(struct workqueue_struct *wq, + struct delayed_work *dwork, + unsigned long delay) +{ + return queue_delayed_work_on(WORK_CPU_UNBOUND, wq, dwork, delay); +} + +/** + * mod_delayed_work - modify delay of or queue a delayed work + * @wq: workqueue to use + * @dwork: work to queue + * @delay: number of jiffies to wait before queueing + * + * mod_delayed_work_on() on local CPU. + */ +static inline bool mod_delayed_work(struct workqueue_struct *wq, + struct delayed_work *dwork, + unsigned long delay) +{ + return mod_delayed_work_on(WORK_CPU_UNBOUND, wq, dwork, delay); +} + +/** + * schedule_work_on - put work task on a specific cpu + * @cpu: cpu to put the work task on + * @work: job to be done + * + * This puts a job on a specific cpu + */ +static inline bool schedule_work_on(int cpu, struct work_struct *work) +{ + return queue_work_on(cpu, system_wq, work); +} + +/** + * schedule_work - put work task in global workqueue + * @work: job to be done + * + * Returns %false if @work was already on the kernel-global workqueue and + * %true otherwise. + * + * This puts a job in the kernel-global workqueue if it was not already + * queued and leaves it in the same position on the kernel-global + * workqueue otherwise. + */ +static inline bool schedule_work(struct work_struct *work) +{ + return queue_work(system_wq, work); +} + +/** + * schedule_delayed_work_on - queue work in global workqueue on CPU after delay + * @cpu: cpu to use + * @dwork: job to be done + * @delay: number of jiffies to wait + * + * After waiting for a given time this puts a job in the kernel-global + * workqueue on the specified CPU. + */ +static inline bool schedule_delayed_work_on(int cpu, struct delayed_work *dwork, + unsigned long delay) +{ + return queue_delayed_work_on(cpu, system_wq, dwork, delay); +} + +/** + * schedule_delayed_work - put work task in global workqueue after delay + * @dwork: job to be done + * @delay: number of jiffies to wait or 0 for immediate execution + * + * After waiting for a given time this puts a job in the kernel-global + * workqueue. + */ +static inline bool schedule_delayed_work(struct delayed_work *dwork, + unsigned long delay) +{ + return queue_delayed_work(system_wq, dwork, delay); +} + +/** + * keventd_up - is workqueue initialized yet? + */ +static inline bool keventd_up(void) +{ + return system_wq != NULL; +} /* * Like above, but uses del_timer() instead of del_timer_sync(). This means, @@ -466,12 +633,12 @@ static inline bool __deprecated flush_delayed_work_sync(struct delayed_work *dwo } #ifndef CONFIG_SMP -static inline long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) +static inline long work_on_cpu(int cpu, long (*fn)(void *), void *arg) { return fn(arg); } #else -long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg); +long work_on_cpu(int cpu, long (*fn)(void *), void *arg); #endif /* CONFIG_SMP */ #ifdef CONFIG_FREEZER @@ -480,4 +647,11 @@ extern bool freeze_workqueues_busy(void); extern void thaw_workqueues(void); #endif /* CONFIG_FREEZER */ +#ifdef CONFIG_SYSFS +int workqueue_sysfs_register(struct workqueue_struct *wq); +#else /* CONFIG_SYSFS */ +static inline int workqueue_sysfs_register(struct workqueue_struct *wq) +{ return 0; } +#endif /* CONFIG_SYSFS */ + #endif diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 9a9367c0c076..021b8a319b9e 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -5,6 +5,7 @@ #define WRITEBACK_H #include <linux/sched.h> +#include <linux/workqueue.h> #include <linux/fs.h> DECLARE_PER_CPU(int, dirty_throttle_leaks); @@ -46,11 +47,16 @@ enum wb_reason { WB_REASON_LAPTOP_TIMER, WB_REASON_FREE_MORE_MEM, WB_REASON_FS_FREE_SPACE, + /* + * There is no bdi forker thread any more and works are done + * by emergency worker, however, this is TPs userland visible + * and we'll be exposing exactly the same information, + * so it has a mismatch name. + */ WB_REASON_FORKER_THREAD, WB_REASON_MAX, }; -extern const char *wb_reason_name[]; /* * A control structure which tells the writeback code what to do. These are @@ -77,6 +83,7 @@ struct writeback_control { unsigned tagged_writepages:1; /* tag-and-write to avoid livelock */ unsigned for_reclaim:1; /* Invoked from the page allocator */ unsigned range_cyclic:1; /* range_start is cyclic */ + unsigned for_sync:1; /* sync(2) WB_SYNC_ALL writeback */ }; /* @@ -91,9 +98,6 @@ int try_to_writeback_inodes_sb(struct super_block *, enum wb_reason reason); int try_to_writeback_inodes_sb_nr(struct super_block *, unsigned long nr, enum wb_reason reason); void sync_inodes_sb(struct super_block *); -long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages, - enum wb_reason reason); -long wb_do_writeback(struct bdi_writeback *wb, int force_wait); void wakeup_flusher_threads(long nr_pages, enum wb_reason reason); void inode_wait_for_writeback(struct inode *inode); diff --git a/include/linux/ww_mutex.h b/include/linux/ww_mutex.h new file mode 100644 index 000000000000..760399a470bd --- /dev/null +++ b/include/linux/ww_mutex.h @@ -0,0 +1,378 @@ +/* + * Wound/Wait Mutexes: blocking mutual exclusion locks with deadlock avoidance + * + * Original mutex implementation started by Ingo Molnar: + * + * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> + * + * Wound/wait implementation: + * Copyright (C) 2013 Canonical Ltd. + * + * This file contains the main data structure and API definitions. + */ + +#ifndef __LINUX_WW_MUTEX_H +#define __LINUX_WW_MUTEX_H + +#include <linux/mutex.h> + +struct ww_class { + atomic_long_t stamp; + struct lock_class_key acquire_key; + struct lock_class_key mutex_key; + const char *acquire_name; + const char *mutex_name; +}; + +struct ww_acquire_ctx { + struct task_struct *task; + unsigned long stamp; + unsigned acquired; +#ifdef CONFIG_DEBUG_MUTEXES + unsigned done_acquire; + struct ww_class *ww_class; + struct ww_mutex *contending_lock; +#endif +#ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lockdep_map dep_map; +#endif +#ifdef CONFIG_DEBUG_WW_MUTEX_SLOWPATH + unsigned deadlock_inject_interval; + unsigned deadlock_inject_countdown; +#endif +}; + +struct ww_mutex { + struct mutex base; + struct ww_acquire_ctx *ctx; +#ifdef CONFIG_DEBUG_MUTEXES + struct ww_class *ww_class; +#endif +}; + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +# define __WW_CLASS_MUTEX_INITIALIZER(lockname, ww_class) \ + , .ww_class = &ww_class +#else +# define __WW_CLASS_MUTEX_INITIALIZER(lockname, ww_class) +#endif + +#define __WW_CLASS_INITIALIZER(ww_class) \ + { .stamp = ATOMIC_LONG_INIT(0) \ + , .acquire_name = #ww_class "_acquire" \ + , .mutex_name = #ww_class "_mutex" } + +#define __WW_MUTEX_INITIALIZER(lockname, class) \ + { .base = { \__MUTEX_INITIALIZER(lockname) } \ + __WW_CLASS_MUTEX_INITIALIZER(lockname, class) } + +#define DEFINE_WW_CLASS(classname) \ + struct ww_class classname = __WW_CLASS_INITIALIZER(classname) + +#define DEFINE_WW_MUTEX(mutexname, ww_class) \ + struct ww_mutex mutexname = __WW_MUTEX_INITIALIZER(mutexname, ww_class) + +/** + * ww_mutex_init - initialize the w/w mutex + * @lock: the mutex to be initialized + * @ww_class: the w/w class the mutex should belong to + * + * Initialize the w/w mutex to unlocked state and associate it with the given + * class. + * + * It is not allowed to initialize an already locked mutex. + */ +static inline void ww_mutex_init(struct ww_mutex *lock, + struct ww_class *ww_class) +{ + __mutex_init(&lock->base, ww_class->mutex_name, &ww_class->mutex_key); + lock->ctx = NULL; +#ifdef CONFIG_DEBUG_MUTEXES + lock->ww_class = ww_class; +#endif +} + +/** + * ww_acquire_init - initialize a w/w acquire context + * @ctx: w/w acquire context to initialize + * @ww_class: w/w class of the context + * + * Initializes an context to acquire multiple mutexes of the given w/w class. + * + * Context-based w/w mutex acquiring can be done in any order whatsoever within + * a given lock class. Deadlocks will be detected and handled with the + * wait/wound logic. + * + * Mixing of context-based w/w mutex acquiring and single w/w mutex locking can + * result in undetected deadlocks and is so forbidden. Mixing different contexts + * for the same w/w class when acquiring mutexes can also result in undetected + * deadlocks, and is hence also forbidden. Both types of abuse will be caught by + * enabling CONFIG_PROVE_LOCKING. + * + * Nesting of acquire contexts for _different_ w/w classes is possible, subject + * to the usual locking rules between different lock classes. + * + * An acquire context must be released with ww_acquire_fini by the same task + * before the memory is freed. It is recommended to allocate the context itself + * on the stack. + */ +static inline void ww_acquire_init(struct ww_acquire_ctx *ctx, + struct ww_class *ww_class) +{ + ctx->task = current; + ctx->stamp = atomic_long_inc_return(&ww_class->stamp); + ctx->acquired = 0; +#ifdef CONFIG_DEBUG_MUTEXES + ctx->ww_class = ww_class; + ctx->done_acquire = 0; + ctx->contending_lock = NULL; +#endif +#ifdef CONFIG_DEBUG_LOCK_ALLOC + debug_check_no_locks_freed((void *)ctx, sizeof(*ctx)); + lockdep_init_map(&ctx->dep_map, ww_class->acquire_name, + &ww_class->acquire_key, 0); + mutex_acquire(&ctx->dep_map, 0, 0, _RET_IP_); +#endif +#ifdef CONFIG_DEBUG_WW_MUTEX_SLOWPATH + ctx->deadlock_inject_interval = 1; + ctx->deadlock_inject_countdown = ctx->stamp & 0xf; +#endif +} + +/** + * ww_acquire_done - marks the end of the acquire phase + * @ctx: the acquire context + * + * Marks the end of the acquire phase, any further w/w mutex lock calls using + * this context are forbidden. + * + * Calling this function is optional, it is just useful to document w/w mutex + * code and clearly designated the acquire phase from actually using the locked + * data structures. + */ +static inline void ww_acquire_done(struct ww_acquire_ctx *ctx) +{ +#ifdef CONFIG_DEBUG_MUTEXES + lockdep_assert_held(ctx); + + DEBUG_LOCKS_WARN_ON(ctx->done_acquire); + ctx->done_acquire = 1; +#endif +} + +/** + * ww_acquire_fini - releases a w/w acquire context + * @ctx: the acquire context to free + * + * Releases a w/w acquire context. This must be called _after_ all acquired w/w + * mutexes have been released with ww_mutex_unlock. + */ +static inline void ww_acquire_fini(struct ww_acquire_ctx *ctx) +{ +#ifdef CONFIG_DEBUG_MUTEXES + mutex_release(&ctx->dep_map, 0, _THIS_IP_); + + DEBUG_LOCKS_WARN_ON(ctx->acquired); + if (!config_enabled(CONFIG_PROVE_LOCKING)) + /* + * lockdep will normally handle this, + * but fail without anyway + */ + ctx->done_acquire = 1; + + if (!config_enabled(CONFIG_DEBUG_LOCK_ALLOC)) + /* ensure ww_acquire_fini will still fail if called twice */ + ctx->acquired = ~0U; +#endif +} + +extern int __must_check __ww_mutex_lock(struct ww_mutex *lock, + struct ww_acquire_ctx *ctx); +extern int __must_check __ww_mutex_lock_interruptible(struct ww_mutex *lock, + struct ww_acquire_ctx *ctx); + +/** + * ww_mutex_lock - acquire the w/w mutex + * @lock: the mutex to be acquired + * @ctx: w/w acquire context, or NULL to acquire only a single lock. + * + * Lock the w/w mutex exclusively for this task. + * + * Deadlocks within a given w/w class of locks are detected and handled with the + * wait/wound algorithm. If the lock isn't immediately avaiable this function + * will either sleep until it is (wait case). Or it selects the current context + * for backing off by returning -EDEADLK (wound case). Trying to acquire the + * same lock with the same context twice is also detected and signalled by + * returning -EALREADY. Returns 0 if the mutex was successfully acquired. + * + * In the wound case the caller must release all currently held w/w mutexes for + * the given context and then wait for this contending lock to be available by + * calling ww_mutex_lock_slow. Alternatively callers can opt to not acquire this + * lock and proceed with trying to acquire further w/w mutexes (e.g. when + * scanning through lru lists trying to free resources). + * + * The mutex must later on be released by the same task that + * acquired it. The task may not exit without first unlocking the mutex. Also, + * kernel memory where the mutex resides must not be freed with the mutex still + * locked. The mutex must first be initialized (or statically defined) before it + * can be locked. memset()-ing the mutex to 0 is not allowed. The mutex must be + * of the same w/w lock class as was used to initialize the acquire context. + * + * A mutex acquired with this function must be released with ww_mutex_unlock. + */ +static inline int ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) +{ + if (ctx) + return __ww_mutex_lock(lock, ctx); + + mutex_lock(&lock->base); + return 0; +} + +/** + * ww_mutex_lock_interruptible - acquire the w/w mutex, interruptible + * @lock: the mutex to be acquired + * @ctx: w/w acquire context + * + * Lock the w/w mutex exclusively for this task. + * + * Deadlocks within a given w/w class of locks are detected and handled with the + * wait/wound algorithm. If the lock isn't immediately avaiable this function + * will either sleep until it is (wait case). Or it selects the current context + * for backing off by returning -EDEADLK (wound case). Trying to acquire the + * same lock with the same context twice is also detected and signalled by + * returning -EALREADY. Returns 0 if the mutex was successfully acquired. If a + * signal arrives while waiting for the lock then this function returns -EINTR. + * + * In the wound case the caller must release all currently held w/w mutexes for + * the given context and then wait for this contending lock to be available by + * calling ww_mutex_lock_slow_interruptible. Alternatively callers can opt to + * not acquire this lock and proceed with trying to acquire further w/w mutexes + * (e.g. when scanning through lru lists trying to free resources). + * + * The mutex must later on be released by the same task that + * acquired it. The task may not exit without first unlocking the mutex. Also, + * kernel memory where the mutex resides must not be freed with the mutex still + * locked. The mutex must first be initialized (or statically defined) before it + * can be locked. memset()-ing the mutex to 0 is not allowed. The mutex must be + * of the same w/w lock class as was used to initialize the acquire context. + * + * A mutex acquired with this function must be released with ww_mutex_unlock. + */ +static inline int __must_check ww_mutex_lock_interruptible(struct ww_mutex *lock, + struct ww_acquire_ctx *ctx) +{ + if (ctx) + return __ww_mutex_lock_interruptible(lock, ctx); + else + return mutex_lock_interruptible(&lock->base); +} + +/** + * ww_mutex_lock_slow - slowpath acquiring of the w/w mutex + * @lock: the mutex to be acquired + * @ctx: w/w acquire context + * + * Acquires a w/w mutex with the given context after a wound case. This function + * will sleep until the lock becomes available. + * + * The caller must have released all w/w mutexes already acquired with the + * context and then call this function on the contended lock. + * + * Afterwards the caller may continue to (re)acquire the other w/w mutexes it + * needs with ww_mutex_lock. Note that the -EALREADY return code from + * ww_mutex_lock can be used to avoid locking this contended mutex twice. + * + * It is forbidden to call this function with any other w/w mutexes associated + * with the context held. It is forbidden to call this on anything else than the + * contending mutex. + * + * Note that the slowpath lock acquiring can also be done by calling + * ww_mutex_lock directly. This function here is simply to help w/w mutex + * locking code readability by clearly denoting the slowpath. + */ +static inline void +ww_mutex_lock_slow(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) +{ + int ret; +#ifdef CONFIG_DEBUG_MUTEXES + DEBUG_LOCKS_WARN_ON(!ctx->contending_lock); +#endif + ret = ww_mutex_lock(lock, ctx); + (void)ret; +} + +/** + * ww_mutex_lock_slow_interruptible - slowpath acquiring of the w/w mutex, interruptible + * @lock: the mutex to be acquired + * @ctx: w/w acquire context + * + * Acquires a w/w mutex with the given context after a wound case. This function + * will sleep until the lock becomes available and returns 0 when the lock has + * been acquired. If a signal arrives while waiting for the lock then this + * function returns -EINTR. + * + * The caller must have released all w/w mutexes already acquired with the + * context and then call this function on the contended lock. + * + * Afterwards the caller may continue to (re)acquire the other w/w mutexes it + * needs with ww_mutex_lock. Note that the -EALREADY return code from + * ww_mutex_lock can be used to avoid locking this contended mutex twice. + * + * It is forbidden to call this function with any other w/w mutexes associated + * with the given context held. It is forbidden to call this on anything else + * than the contending mutex. + * + * Note that the slowpath lock acquiring can also be done by calling + * ww_mutex_lock_interruptible directly. This function here is simply to help + * w/w mutex locking code readability by clearly denoting the slowpath. + */ +static inline int __must_check +ww_mutex_lock_slow_interruptible(struct ww_mutex *lock, + struct ww_acquire_ctx *ctx) +{ +#ifdef CONFIG_DEBUG_MUTEXES + DEBUG_LOCKS_WARN_ON(!ctx->contending_lock); +#endif + return ww_mutex_lock_interruptible(lock, ctx); +} + +extern void ww_mutex_unlock(struct ww_mutex *lock); + +/** + * ww_mutex_trylock - tries to acquire the w/w mutex without acquire context + * @lock: mutex to lock + * + * Trylocks a mutex without acquire context, so no deadlock detection is + * possible. Returns 1 if the mutex has been acquired successfully, 0 otherwise. + */ +static inline int __must_check ww_mutex_trylock(struct ww_mutex *lock) +{ + return mutex_trylock(&lock->base); +} + +/*** + * ww_mutex_destroy - mark a w/w mutex unusable + * @lock: the mutex to be destroyed + * + * This function marks the mutex uninitialized, and any subsequent + * use of the mutex is forbidden. The mutex must not be locked when + * this function is called. + */ +static inline void ww_mutex_destroy(struct ww_mutex *lock) +{ + mutex_destroy(&lock->base); +} + +/** + * ww_mutex_is_locked - is the w/w mutex locked + * @lock: the mutex to be queried + * + * Returns 1 if the mutex is locked, 0 if unlocked. + */ +static inline bool ww_mutex_is_locked(struct ww_mutex *lock) +{ + return mutex_is_locked(&lock->base); +} + +#endif diff --git a/include/linux/xattr.h b/include/linux/xattr.h index fdbafc6841cf..91b0a68d38dc 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -31,7 +31,7 @@ struct xattr_handler { }; struct xattr { - char *name; + const char *name; void *value; size_t value_len; }; diff --git a/include/linux/zbud.h b/include/linux/zbud.h new file mode 100644 index 000000000000..2571a5cfa5fc --- /dev/null +++ b/include/linux/zbud.h @@ -0,0 +1,22 @@ +#ifndef _ZBUD_H_ +#define _ZBUD_H_ + +#include <linux/types.h> + +struct zbud_pool; + +struct zbud_ops { + int (*evict)(struct zbud_pool *pool, unsigned long handle); +}; + +struct zbud_pool *zbud_create_pool(gfp_t gfp, struct zbud_ops *ops); +void zbud_destroy_pool(struct zbud_pool *pool); +int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp, + unsigned long *handle); +void zbud_free(struct zbud_pool *pool, unsigned long handle); +int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries); +void *zbud_map(struct zbud_pool *pool, unsigned long handle); +void zbud_unmap(struct zbud_pool *pool, unsigned long handle); +u64 zbud_get_pool_size(struct zbud_pool *pool); + +#endif /* _ZBUD_H_ */ |