From 927a7c9c1793def3a55d60c926d3945528e6bf1b Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Mar 2010 04:47:19 +0000 Subject: dmaengine: shdma: Enable on SH-Mobile ARM Enable the shdma dmaengine driver on SH-Mobile ARM. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- include/linux/serial_sci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index f5364a1..837efa4 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -3,7 +3,7 @@ #include #ifdef CONFIG_SERIAL_SH_SCI_DMA -#include +#include #endif /* -- cgit v1.1 From ea95450eede38ca695db8c2202b1f5c7a0f9ebbb Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 20 May 2010 16:31:56 +0000 Subject: fbdev: add a MIPI DSI header This header adds defines for MIPI DSI and DCS commands and data formats. See http://www.mipi.org/ for details. Signed-off-by: Guennadi Liakhovetski Acked-by: Tomi Valkeinen Signed-off-by: Paul Mundt --- include/video/mipi_display.h | 130 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 include/video/mipi_display.h (limited to 'include') diff --git a/include/video/mipi_display.h b/include/video/mipi_display.h new file mode 100644 index 0000000..ddcc8ca --- /dev/null +++ b/include/video/mipi_display.h @@ -0,0 +1,130 @@ +/* + * Defines for Mobile Industry Processor Interface (MIPI(R)) + * Display Working Group standards: DSI, DCS, DBI, DPI + * + * Copyright (C) 2010 Guennadi Liakhovetski + * Copyright (C) 2006 Nokia Corporation + * Author: Imre Deak + * + * 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 MIPI_DISPLAY_H +#define MIPI_DISPLAY_H + +/* MIPI DSI Processor-to-Peripheral transaction types */ +enum { + MIPI_DSI_V_SYNC_START = 0x01, + MIPI_DSI_V_SYNC_END = 0x11, + MIPI_DSI_H_SYNC_START = 0x21, + MIPI_DSI_H_SYNC_END = 0x31, + + MIPI_DSI_COLOR_MODE_OFF = 0x02, + MIPI_DSI_COLOR_MODE_ON = 0x12, + MIPI_DSI_SHUTDOWN_PERIPHERAL = 0x22, + MIPI_DSI_TURN_ON_PERIPHERAL = 0x32, + + MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM = 0x03, + MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM = 0x13, + MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM = 0x23, + + MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM = 0x04, + MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM = 0x14, + MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM = 0x24, + + MIPI_DSI_DCS_SHORT_WRITE = 0x05, + MIPI_DSI_DCS_SHORT_WRITE_PARAM = 0x15, + + MIPI_DSI_DCS_READ = 0x06, + + MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE = 0x37, + + MIPI_DSI_END_OF_TRANSMISSION = 0x08, + + MIPI_DSI_NULL_PACKET = 0x09, + MIPI_DSI_BLANKING_PACKET = 0x19, + MIPI_DSI_GENERIC_LONG_WRITE = 0x29, + MIPI_DSI_DCS_LONG_WRITE = 0x39, + + MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 = 0x0c, + MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24 = 0x1c, + MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16 = 0x2c, + + MIPI_DSI_PACKED_PIXEL_STREAM_30 = 0x0d, + MIPI_DSI_PACKED_PIXEL_STREAM_36 = 0x1d, + MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12 = 0x3d, + + MIPI_DSI_PACKED_PIXEL_STREAM_16 = 0x0e, + MIPI_DSI_PACKED_PIXEL_STREAM_18 = 0x1e, + MIPI_DSI_PIXEL_STREAM_3BYTE_18 = 0x2e, + MIPI_DSI_PACKED_PIXEL_STREAM_24 = 0x3e, +}; + +/* MIPI DSI Peripheral-to-Processor transaction types */ +enum { + MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT = 0x02, + MIPI_DSI_RX_END_OF_TRANSMISSION = 0x08, + MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE = 0x11, + MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE = 0x12, + MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE = 0x1a, + MIPI_DSI_RX_DCS_LONG_READ_RESPONSE = 0x1c, + MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE = 0x21, + MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE = 0x22, +}; + +/* MIPI DCS commands */ +enum { + MIPI_DCS_NOP = 0x00, + MIPI_DCS_SOFT_RESET = 0x01, + MIPI_DCS_GET_DISPLAY_ID = 0x04, + MIPI_DCS_GET_RED_CHANNEL = 0x06, + MIPI_DCS_GET_GREEN_CHANNEL = 0x07, + MIPI_DCS_GET_BLUE_CHANNEL = 0x08, + MIPI_DCS_GET_DISPLAY_STATUS = 0x09, + MIPI_DCS_GET_POWER_MODE = 0x0A, + MIPI_DCS_GET_ADDRESS_MODE = 0x0B, + MIPI_DCS_GET_PIXEL_FORMAT = 0x0C, + MIPI_DCS_GET_DISPLAY_MODE = 0x0D, + MIPI_DCS_GET_SIGNAL_MODE = 0x0E, + MIPI_DCS_GET_DIAGNOSTIC_RESULT = 0x0F, + MIPI_DCS_ENTER_SLEEP_MODE = 0x10, + MIPI_DCS_EXIT_SLEEP_MODE = 0x11, + MIPI_DCS_ENTER_PARTIAL_MODE = 0x12, + MIPI_DCS_ENTER_NORMAL_MODE = 0x13, + MIPI_DCS_EXIT_INVERT_MODE = 0x20, + MIPI_DCS_ENTER_INVERT_MODE = 0x21, + MIPI_DCS_SET_GAMMA_CURVE = 0x26, + MIPI_DCS_SET_DISPLAY_OFF = 0x28, + MIPI_DCS_SET_DISPLAY_ON = 0x29, + MIPI_DCS_SET_COLUMN_ADDRESS = 0x2A, + MIPI_DCS_SET_PAGE_ADDRESS = 0x2B, + MIPI_DCS_WRITE_MEMORY_START = 0x2C, + MIPI_DCS_WRITE_LUT = 0x2D, + MIPI_DCS_READ_MEMORY_START = 0x2E, + MIPI_DCS_SET_PARTIAL_AREA = 0x30, + MIPI_DCS_SET_SCROLL_AREA = 0x33, + MIPI_DCS_SET_TEAR_OFF = 0x34, + MIPI_DCS_SET_TEAR_ON = 0x35, + MIPI_DCS_SET_ADDRESS_MODE = 0x36, + MIPI_DCS_SET_SCROLL_START = 0x37, + MIPI_DCS_EXIT_IDLE_MODE = 0x38, + MIPI_DCS_ENTER_IDLE_MODE = 0x39, + MIPI_DCS_SET_PIXEL_FORMAT = 0x3A, + MIPI_DCS_WRITE_MEMORY_CONTINUE = 0x3C, + MIPI_DCS_READ_MEMORY_CONTINUE = 0x3E, + MIPI_DCS_SET_TEAR_SCANLINE = 0x44, + MIPI_DCS_GET_SCANLINE = 0x45, + MIPI_DCS_READ_DDB_START = 0xA1, + MIPI_DCS_READ_DDB_CONTINUE = 0xA8, +}; + +/* MIPI DCS pixel formats */ +#define MIPI_DCS_PIXEL_FMT_24BIT 7 +#define MIPI_DCS_PIXEL_FMT_18BIT 6 +#define MIPI_DCS_PIXEL_FMT_16BIT 5 +#define MIPI_DCS_PIXEL_FMT_12BIT 3 +#define MIPI_DCS_PIXEL_FMT_8BIT 2 +#define MIPI_DCS_PIXEL_FMT_3BIT 1 + +#endif -- cgit v1.1 From 1430e006a36da5401ad4420711b5a702ba17afa8 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 21 May 2010 15:15:41 +0000 Subject: sh: add a YUV422 output data format, that is also supported by LCDC The LCDC block is allowed to use one of the two output data formats, when used with MIPI DSI: RGB24 and YUV422. YUV422 is not currently handled by the LCDC driver, but we have to add a define for it for MIPI. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- include/video/sh_mobile_lcdc.h | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h index 2cc893f..5eaea78 100644 --- a/include/video/sh_mobile_lcdc.h +++ b/include/video/sh_mobile_lcdc.h @@ -3,24 +3,27 @@ #include -enum { RGB8, /* 24bpp, 8:8:8 */ - RGB9, /* 18bpp, 9:9 */ - RGB12A, /* 24bpp, 12:12 */ - RGB12B, /* 12bpp */ - RGB16, /* 16bpp */ - RGB18, /* 18bpp */ - RGB24, /* 24bpp */ - SYS8A, /* 24bpp, 8:8:8 */ - SYS8B, /* 18bpp, 8:8:2 */ - SYS8C, /* 18bpp, 2:8:8 */ - SYS8D, /* 16bpp, 8:8 */ - SYS9, /* 18bpp, 9:9 */ - SYS12, /* 24bpp, 12:12 */ - SYS16A, /* 16bpp */ - SYS16B, /* 18bpp, 16:2 */ - SYS16C, /* 18bpp, 2:16 */ - SYS18, /* 18bpp */ - SYS24 };/* 24bpp */ +enum { + RGB8, /* 24bpp, 8:8:8 */ + RGB9, /* 18bpp, 9:9 */ + RGB12A, /* 24bpp, 12:12 */ + RGB12B, /* 12bpp */ + RGB16, /* 16bpp */ + RGB18, /* 18bpp */ + RGB24, /* 24bpp */ + YUV422, /* 16bpp */ + SYS8A, /* 24bpp, 8:8:8 */ + SYS8B, /* 18bpp, 8:8:2 */ + SYS8C, /* 18bpp, 2:8:8 */ + SYS8D, /* 16bpp, 8:8 */ + SYS9, /* 18bpp, 9:9 */ + SYS12, /* 24bpp, 12:12 */ + SYS16A, /* 16bpp */ + SYS16B, /* 18bpp, 16:2 */ + SYS16C, /* 18bpp, 2:16 */ + SYS18, /* 18bpp */ + SYS24, /* 24bpp */ +}; enum { LCDC_CHAN_DISABLED = 0, LCDC_CHAN_MAINLCD, -- cgit v1.1 From 9fd04fe34af36344f61ebb24cc653726c231356e Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sun, 23 May 2010 14:00:43 +0000 Subject: sh-mobile: add support for displays, connected over the MIPI bus Some SH-mobile SoCs have a MIPI DSI controller, that can be used to connect MIPI displays to LCDC. This patch adds a platform driver for SH-mobile MIPI DSI unit. It uses existing hooks in the sh_mobile_lcdcfb.c driver for display activation and deactivation. Signed-off-by: Guennadi Liakhovetski Tested-by: Damian Hobson-Garcia Signed-off-by: Paul Mundt --- include/video/sh_mipi_dsi.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 include/video/sh_mipi_dsi.h (limited to 'include') diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h new file mode 100644 index 0000000..18bca08 --- /dev/null +++ b/include/video/sh_mipi_dsi.h @@ -0,0 +1,35 @@ +/* + * Public SH-mobile MIPI DSI header + * + * Copyright (C) 2010 Guennadi Liakhovetski + * + * 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 VIDEO_SH_MIPI_DSI_H +#define VIDEO_SH_MIPI_DSI_H + +enum sh_mipi_dsi_data_fmt { + MIPI_RGB888, + MIPI_RGB565, + MIPI_RGB666_LP, + MIPI_RGB666, + MIPI_BGR888, + MIPI_BGR565, + MIPI_BGR666_LP, + MIPI_BGR666, + MIPI_YUYV, + MIPI_UYVY, + MIPI_YUV420_L, + MIPI_YUV420, +}; + +struct sh_mobile_lcdc_chan_cfg; + +struct sh_mipi_dsi_info { + enum sh_mipi_dsi_data_fmt data_format; + struct sh_mobile_lcdc_chan_cfg *lcd_chan; +}; + +#endif -- cgit v1.1 From 75b93489b449db4a34f0424c72f51821d985f52f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sun, 23 May 2010 16:39:02 +0000 Subject: serial: add a new port type, found on some sh-mobile SoCs Such ports are found, e.g., on SH7372. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- include/linux/serial_core.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index f10db6e..5228320 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -186,6 +186,9 @@ #define PORT_ALTERA_JTAGUART 91 #define PORT_ALTERA_UART 92 +/* SH-SCI */ +#define PORT_SCIFB 93 + #ifdef __KERNEL__ #include -- cgit v1.1 From 19001c8c5bfa032ed45b10dfe48e355f5df88c61 Mon Sep 17 00:00:00 2001 From: Alex Nixon Date: Mon, 9 Feb 2009 12:05:46 -0800 Subject: xen: Rename the balloon lock * xen_create_contiguous_region needs access to the balloon lock to ensure memory doesn't change under its feet, so expose the balloon lock * Change the name of the lock to xen_reservation_lock, to imply it's now less-specific usage. [ Impact: cleanup ] Signed-off-by: Alex Nixon Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Konrad Rzeszutek Wilk --- include/xen/interface/memory.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h index af36ead..e6adce6 100644 --- a/include/xen/interface/memory.h +++ b/include/xen/interface/memory.h @@ -9,6 +9,8 @@ #ifndef __XEN_PUBLIC_MEMORY_H__ #define __XEN_PUBLIC_MEMORY_H__ +#include + /* * Increase or decrease the specified domain's memory reservation. Returns a * -ve errcode on failure, or the # extents successfully allocated or freed. @@ -142,4 +144,10 @@ struct xen_translate_gpfn_list { }; DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list); + +/* + * Prevent the balloon driver from changing the memory reservation + * during a driver critical region. + */ +extern spinlock_t xen_reservation_lock; #endif /* __XEN_PUBLIC_MEMORY_H__ */ -- cgit v1.1 From 08bbc9da92f7e44b9c208c6a1adba70c403b255e Mon Sep 17 00:00:00 2001 From: Alex Nixon Date: Mon, 9 Feb 2009 12:05:46 -0800 Subject: xen: Add xen_create_contiguous_region A memory region must be physically contiguous in order to be accessed through DMA. This patch adds xen_create_contiguous_region, which ensures a region of contiguous virtual memory is also physically contiguous. Based on Stephen Tweedie's port of the 2.6.18-xen version. Remove contiguous_bitmap[] as it's no longer needed. Ported from linux-2.6.18-xen.hg 707:e410857fd83c [ Impact: add Xen-internal API to make pages phys-contig ] Signed-off-by: Alex Nixon Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- include/xen/interface/memory.h | 42 ++++++++++++++++++++++++++++++++++++++++++ include/xen/xen-ops.h | 6 ++++++ 2 files changed, 48 insertions(+) (limited to 'include') diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h index e6adce6..d3938d3 100644 --- a/include/xen/interface/memory.h +++ b/include/xen/interface/memory.h @@ -55,6 +55,48 @@ struct xen_memory_reservation { DEFINE_GUEST_HANDLE_STRUCT(xen_memory_reservation); /* + * An atomic exchange of memory pages. If return code is zero then + * @out.extent_list provides GMFNs of the newly-allocated memory. + * Returns zero on complete success, otherwise a negative error code. + * On complete success then always @nr_exchanged == @in.nr_extents. + * On partial success @nr_exchanged indicates how much work was done. + */ +#define XENMEM_exchange 11 +struct xen_memory_exchange { + /* + * [IN] Details of memory extents to be exchanged (GMFN bases). + * Note that @in.address_bits is ignored and unused. + */ + struct xen_memory_reservation in; + + /* + * [IN/OUT] Details of new memory extents. + * We require that: + * 1. @in.domid == @out.domid + * 2. @in.nr_extents << @in.extent_order == + * @out.nr_extents << @out.extent_order + * 3. @in.extent_start and @out.extent_start lists must not overlap + * 4. @out.extent_start lists GPFN bases to be populated + * 5. @out.extent_start is overwritten with allocated GMFN bases + */ + struct xen_memory_reservation out; + + /* + * [OUT] Number of input extents that were successfully exchanged: + * 1. The first @nr_exchanged input extents were successfully + * deallocated. + * 2. The corresponding first entries in the output extent list correctly + * indicate the GMFNs that were successfully exchanged. + * 3. All other input and output extents are untouched. + * 4. If not all input exents are exchanged then the return code of this + * command will be non-zero. + * 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER! + */ + unsigned long nr_exchanged; +}; + +DEFINE_GUEST_HANDLE_STRUCT(xen_memory_exchange); +/* * Returns the maximum machine frame number of mapped RAM in this system. * This command always succeeds (it never returns an error code). * arg == NULL. diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index 883a21b..d789c93 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -14,4 +14,10 @@ void xen_mm_unpin_all(void); void xen_timer_resume(void); void xen_arch_resume(void); +extern unsigned long *xen_contiguous_bitmap; +int xen_create_contiguous_region(unsigned long vstart, unsigned int order, + unsigned int address_bits); + +void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order); + #endif /* INCLUDE_XEN_OPS_H */ -- cgit v1.1 From 808be4b22f47886d2279852ada3d186fc20909bc Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 17 Jul 2010 13:57:03 +0300 Subject: Add s3c-adc-battery driver s3c-adc-battery is driver for monitoring and charging battery on iPAQ H1930/H1940/RX1950. It depends on s3c-adc driver to get battery voltage and current. Signed-off-by: Vasily Khoruzhick Signed-off-by: Anton Vorontsov --- include/linux/s3c_adc_battery.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 include/linux/s3c_adc_battery.h (limited to 'include') diff --git a/include/linux/s3c_adc_battery.h b/include/linux/s3c_adc_battery.h new file mode 100644 index 0000000..dbce22f --- /dev/null +++ b/include/linux/s3c_adc_battery.h @@ -0,0 +1,36 @@ +#ifndef _S3C_ADC_BATTERY_H +#define _S3C_ADC_BATTERY_H + +struct s3c_adc_bat_thresh { + int volt; /* mV */ + int cur; /* mA */ + int level; /* percent */ +}; + +struct s3c_adc_bat_pdata { + int (*init)(void); + void (*exit)(void); + void (*enable_charger)(void); + void (*disable_charger)(void); + + int gpio_charge_finished; + + const struct s3c_adc_bat_thresh *lut_noac; + unsigned int lut_noac_cnt; + const struct s3c_adc_bat_thresh *lut_acin; + unsigned int lut_acin_cnt; + + const unsigned int volt_channel; + const unsigned int current_channel; + const unsigned int backup_volt_channel; + + const unsigned int volt_mult; + const unsigned int current_mult; + const unsigned int backup_volt_mult; + const unsigned int internal_impedance; + + const unsigned int backup_volt_max; + const unsigned int backup_volt_min; +}; + +#endif -- cgit v1.1 From a0d40c80256e31b23849f2ba781b74bf0218a1fa Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 26 Mar 2010 15:28:51 -0700 Subject: vmap: add flag to allow lazy unmap to be disabled at runtime Add a flag to force lazy_max_pages() to zero to prevent any outstanding mapped pages. We'll need this for Xen. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Nick Piggin --- include/linux/vmalloc.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 227c2a5..b840fda 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -7,6 +7,8 @@ struct vm_area_struct; /* vma defining user mapping in mm_types.h */ +extern bool vmap_lazy_unmap; + /* bits in flags of vmalloc's vm_struct below */ #define VM_IOREMAP 0x00000001 /* ioremap() and friends */ #define VM_ALLOC 0x00000002 /* vmalloc() */ -- cgit v1.1 From b097186fd29d5bc5a26d1ae87995821ffc27b66e Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 11 May 2010 10:05:49 -0400 Subject: swiotlb-xen: SWIOTLB library for Xen PV guest with PCI passthrough. This patchset: PV guests under Xen are running in an non-contiguous memory architecture. When PCI pass-through is utilized, this necessitates an IOMMU for translating bus (DMA) to virtual and vice-versa and also providing a mechanism to have contiguous pages for device drivers operations (say DMA operations). Specifically, under Xen the Linux idea of pages is an illusion. It assumes that pages start at zero and go up to the available memory. To help with that, the Linux Xen MMU provides a lookup mechanism to translate the page frame numbers (PFN) to machine frame numbers (MFN) and vice-versa. The MFN are the "real" frame numbers. Furthermore memory is not contiguous. Xen hypervisor stitches memory for guests from different pools, which means there is no guarantee that PFN==MFN and PFN+1==MFN+1. Lastly with Xen 4.0, pages (in debug mode) are allocated in descending order (high to low), meaning the guest might never get any MFN's under the 4GB mark. Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Jeremy Fitzhardinge Cc: FUJITA Tomonori Cc: Albert Herranz Cc: Ian Campbell --- include/xen/swiotlb-xen.h | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 include/xen/swiotlb-xen.h (limited to 'include') diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h new file mode 100644 index 0000000..2ea2fdc --- /dev/null +++ b/include/xen/swiotlb-xen.h @@ -0,0 +1,65 @@ +#ifndef __LINUX_SWIOTLB_XEN_H +#define __LINUX_SWIOTLB_XEN_H + +#include + +extern void xen_swiotlb_init(int verbose); + +extern void +*xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags); + +extern void +xen_swiotlb_free_coherent(struct device *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle); + +extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + struct dma_attrs *attrs); + +extern void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, + size_t size, enum dma_data_direction dir, + struct dma_attrs *attrs); +/* +extern int +xen_swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, + enum dma_data_direction dir); + +extern void +xen_swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, + enum dma_data_direction dir); +*/ +extern int +xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, + int nelems, enum dma_data_direction dir, + struct dma_attrs *attrs); + +extern void +xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, + int nelems, enum dma_data_direction dir, + struct dma_attrs *attrs); + +extern void +xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, + size_t size, enum dma_data_direction dir); + +extern void +xen_swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, + int nelems, enum dma_data_direction dir); + +extern void +xen_swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, + size_t size, enum dma_data_direction dir); + +extern void +xen_swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, + int nelems, enum dma_data_direction dir); + +extern int +xen_swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); + +extern int +xen_swiotlb_dma_supported(struct device *hwdev, u64 mask); + +#endif /* __LINUX_SWIOTLB_XEN_H */ -- cgit v1.1 From b5272b509a8570bb559156001e74ee162c5cb96a Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 21 Jul 2010 10:13:06 +0000 Subject: sh: add a list of parent configurations to struct clk Many system clocks can select a parent by writing a value to a specific field in the configuration register. Add a list of parents and location and width of the source selection field in the clock configuration register to struct clk to assist in clk_set_parent() implementation. Signed-off-by: Guennadi Liakhovetski Acked-by: Magnus Damm Signed-off-by: Paul Mundt --- include/linux/sh_clk.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 1636d1e..08a07b9 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -25,6 +25,10 @@ struct clk { int id; struct clk *parent; + struct clk **parent_table; /* list of parents to */ + unsigned short parent_num; /* choose between */ + unsigned char src_shift; /* source clock field in the */ + unsigned char src_width; /* configuration register */ struct clk_ops *ops; struct list_head children; -- cgit v1.1 From b3dd51a8a6ce2e618e8a1be8fa0e7d3d4733c300 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 21 Jul 2010 10:13:10 +0000 Subject: sh: add a reparent function to DIV6 clocks Add support for reparenting of div6 clocks on SuperH and SH-Mobile SoCs. Signed-off-by: Guennadi Liakhovetski Acked-by: Magnus Damm Signed-off-by: Paul Mundt --- include/linux/sh_clk.h | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 08a07b9..875ce50 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -142,13 +142,22 @@ int sh_clk_div4_enable_register(struct clk *clks, int nr, int sh_clk_div4_reparent_register(struct clk *clks, int nr, struct clk_div4_table *table); -#define SH_CLK_DIV6(_parent, _reg, _flags) \ -{ \ - .parent = _parent, \ - .enable_reg = (void __iomem *)_reg, \ - .flags = _flags, \ +#define SH_CLK_DIV6_EXT(_parent, _reg, _flags, _parents, \ + _num_parents, _src_shift, _src_width) \ +{ \ + .parent = _parent, \ + .enable_reg = (void __iomem *)_reg, \ + .flags = _flags, \ + .parent_table = _parents, \ + .parent_num = _num_parents, \ + .src_shift = _src_shift, \ + .src_width = _src_width, \ } +#define SH_CLK_DIV6(_parent, _reg, _flags) \ + SH_CLK_DIV6_EXT(_parent, _reg, _flags, NULL, 0, 0, 0) + int sh_clk_div6_register(struct clk *clks, int nr); +int sh_clk_div6_reparent_register(struct clk *clks, int nr); #endif /* __SH_CLOCK_H */ -- cgit v1.1 From c2439398170be9d7af28eb3ab59593369cb303f3 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 21 Jul 2010 10:13:17 +0000 Subject: sh: add a parameter to LCDC driver's .display_on() callback HDMI support for the sh_mobile_lcdc framebuffer driver will require a 'struct fb_info *' pointer for its .display_on() callback. While at it fix kfr2r09 framebuffer modular build. Signed-off-by: Guennadi Liakhovetski Acked-by: Magnus Damm Signed-off-by: Paul Mundt --- include/video/sh_mobile_lcdc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h index 2439344..55d700e 100644 --- a/include/video/sh_mobile_lcdc.h +++ b/include/video/sh_mobile_lcdc.h @@ -55,7 +55,7 @@ struct sh_mobile_lcdc_board_cfg { struct sh_mobile_lcdc_sys_bus_ops *sys_ops); void (*start_transfer)(void *board_data, void *sys_ops_handle, struct sh_mobile_lcdc_sys_bus_ops *sys_ops); - void (*display_on)(void *board_data); + void (*display_on)(void *board_data, struct fb_info *info); void (*display_off)(void *board_data); }; -- cgit v1.1 From 6011bdeaa6089d49c02de69f05980da7bad314ab Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 21 Jul 2010 10:13:21 +0000 Subject: fbdev: sh-mobile: HDMI support for SH-Mobile SoCs Some SH-Mobile SoCs have an HDMI controller and a PHY, attached to one of their LCDC interfaces. This patch adds a preliminary static support for such controllers, this means, that only the 720p mode is handled ATM. Support for more modes and a dynamic switching between them will be added by a follow up patch. Signed-off-by: Guennadi Liakhovetski Acked-by: Magnus Damm Signed-off-by: Paul Mundt --- include/video/sh_mobile_hdmi.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 include/video/sh_mobile_hdmi.h (limited to 'include') diff --git a/include/video/sh_mobile_hdmi.h b/include/video/sh_mobile_hdmi.h new file mode 100644 index 0000000..577cf18 --- /dev/null +++ b/include/video/sh_mobile_hdmi.h @@ -0,0 +1,22 @@ +/* + * SH-Mobile High-Definition Multimedia Interface (HDMI) + * + * Copyright (C) 2010, Guennadi Liakhovetski + * + * 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 SH_MOBILE_HDMI_H +#define SH_MOBILE_HDMI_H + +struct sh_mobile_lcdc_chan_cfg; +struct device; + +struct sh_mobile_hdmi_info { + struct sh_mobile_lcdc_chan_cfg *lcd_chan; + struct device *lcd_dev; +}; + +#endif -- cgit v1.1 From 5aa9a2cbc037b2ec34b76619d233852d2d17b502 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 4 Jun 2010 03:07:34 +0200 Subject: [ARM] wm97xx_batt: remove now useless header file Signed-off-by: Marek Vasut Acked-by: Mark Brown Signed-off-by: Eric Miao --- include/linux/wm97xx_batt.h | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 include/linux/wm97xx_batt.h (limited to 'include') diff --git a/include/linux/wm97xx_batt.h b/include/linux/wm97xx_batt.h deleted file mode 100644 index a1d6419..0000000 --- a/include/linux/wm97xx_batt.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _LINUX_WM97XX_BAT_H -#define _LINUX_WM97XX_BAT_H - -#include - -#warning This file will be removed soon, use wm97xx.h instead! - -#define wm97xx_batt_info wm97xx_batt_pdata - -#ifdef CONFIG_BATTERY_WM97XX -void wm97xx_bat_set_pdata(struct wm97xx_batt_info *data); -#else -static inline void wm97xx_bat_set_pdata(struct wm97xx_batt_info *data) {} -#endif - -#endif -- cgit v1.1 From 2dc11581376829303b98eadb2de253bee065a56a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 6 Aug 2010 09:25:50 -0600 Subject: of/device: Replace struct of_device with struct platform_device of_device is just an alias for platform_device, so remove it entirely. Also replace to_of_device() with to_platform_device() and update comment blocks. This patch was initially generated from the following semantic patch, and then edited by hand to pick up the bits that coccinelle didn't catch. @@ @@ -struct of_device +struct platform_device Signed-off-by: Grant Likely Reviewed-by: David S. Miller --- include/linux/of_device.h | 16 ---------------- include/linux/of_platform.h | 14 +++++++++++--- 2 files changed, 11 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 35aa44a..835f85e 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -1,20 +1,6 @@ #ifndef _LINUX_OF_DEVICE_H #define _LINUX_OF_DEVICE_H -/* - * The of_device *was* a kind of "base class" that was a superset of - * struct device for use by devices attached to an OF node and probed - * using OF properties. However, the important bit of OF-style - * probing, namely the device node pointer, has been moved into the - * common struct device when CONFIG_OF is set to make OF-style probing - * available to all bus types. So now, just make of_device and - * platform_device equivalent so that current of_platform bus users - * can be transparently migrated over to using the platform bus. - * - * This line will go away once all references to of_device are removed - * from the kernel. - */ -#define of_device platform_device #include #include /* temporary until merge */ @@ -23,8 +9,6 @@ #include #include -#define to_of_device(d) container_of(d, struct of_device, dev) - 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); diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 4e6d989..a68716a 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -19,9 +19,17 @@ #include #include -/* - * An of_platform_driver driver is attached to a basic of_device on - * the "platform bus" (platform_bus_type). +/** + * of_platform_driver - Legacy of-aware driver for platform devices. + * + * An of_platform_driver driver is attached to a basic platform_device on + * ether the "platform bus" (platform_bus_type), or the ibm ebus + * (ibmebus_bus_type). + * + * of_platform_driver is being phased out when used with the platform_bus_type, + * and regular platform_drivers should be used instead. When the transition + * is complete, only ibmebus will be using this structure, and the + * platform_driver member of this structure will be removed. */ struct of_platform_driver { -- cgit v1.1 From c17c2f892e23a3c70281a4e79bd7c2c226b1a561 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 6 Aug 2010 13:55:10 +1000 Subject: drm: Fix support for PCI domains (For some reason I thought that went in ages ago ...) This fixes support for PCI domains in what should hopefully be a backward compatible way along with a change to libdrm. When the interface version is set to 1.4, we assume userspace understands domains and the world is at peace. We thus pass proper domain numbers instead of 0 to userspace. The newer libdrm will then try 1.4 first, and fallback to 1.1, along with ignoring domains in the later case (well, except on alpha of course) Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Dave Airlie --- include/drm/drmP.h | 22 ++++++++++++++++------ include/drm/drm_core.h | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index e2a4da7..2a512bc 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1075,7 +1075,6 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev, return ((dev->driver->driver_features & feature) ? 1 : 0); } - static inline int drm_dev_to_irq(struct drm_device *dev) { if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) @@ -1084,11 +1083,22 @@ static inline int drm_dev_to_irq(struct drm_device *dev) return dev->pdev->irq; } -#ifdef __alpha__ -#define drm_get_pci_domain(dev) dev->hose->index -#else -#define drm_get_pci_domain(dev) 0 -#endif +static inline int drm_get_pci_domain(struct drm_device *dev) +{ + if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) + return 0; + +#ifndef __alpha__ + /* For historical reasons, drm_get_pci_domain() is busticated + * on most archs and has to remain so for userspace interface + * < 1.4, except on alpha which was right from the beginning + */ + if (dev->if_version < 0x10004) + return 0; +#endif /* __alpha__ */ + + return pci_domain_nr(dev->pdev->bus); +} #if __OS_HAS_AGP static inline int drm_core_has_AGP(struct drm_device *dev) diff --git a/include/drm/drm_core.h b/include/drm/drm_core.h index 3167390..4e75238 100644 --- a/include/drm/drm_core.h +++ b/include/drm/drm_core.h @@ -27,7 +27,7 @@ #define CORE_DATE "20060810" #define DRM_IF_MAJOR 1 -#define DRM_IF_MINOR 3 +#define DRM_IF_MINOR 4 #define CORE_MAJOR 1 #define CORE_MINOR 1 -- cgit v1.1 From fb439640145df0d3af7eacb83a19d8eb0a24002a Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 3 Aug 2010 14:38:16 -0400 Subject: drm: Remove unused fields from drm_display_info Signed-off-by: Adam Jackson Signed-off-by: Dave Airlie --- include/drm/drm_crtc.h | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 93a1a31..606eb93 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -190,49 +190,16 @@ enum subpixel_order { */ struct drm_display_info { char name[DRM_DISPLAY_INFO_LEN]; - /* Input info */ - bool serration_vsync; - bool sync_on_green; - bool composite_sync; - bool separate_syncs; - bool blank_to_black; - unsigned char video_level; - bool digital; + /* Physical size */ unsigned int width_mm; unsigned int height_mm; - /* Display parameters */ - unsigned char gamma; /* FIXME: storage format */ - bool gtf_supported; - bool standard_color; - enum { - monochrome = 0, - rgb, - other, - unknown, - } display_type; - bool active_off_supported; - bool suspend_supported; - bool standby_supported; - - /* Color info FIXME: storage format */ - unsigned short redx, redy; - unsigned short greenx, greeny; - unsigned short bluex, bluey; - unsigned short whitex, whitey; - /* Clock limits FIXME: storage format */ unsigned int min_vfreq, max_vfreq; unsigned int min_hfreq, max_hfreq; unsigned int pixel_clock; - /* White point indices FIXME: storage format */ - unsigned int wpx1, wpy1; - unsigned int wpgamma1; - unsigned int wpx2, wpy2; - unsigned int wpgamma2; - enum subpixel_order subpixel_order; char *raw_edid; /* if any */ -- cgit v1.1 From 4d76a22134d5a5ad259fd667f3d2b215b7e71d10 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 3 Aug 2010 14:38:17 -0400 Subject: drm/edid: Add detailed block walk for CEA extensions Signed-off-by: Adam Jackson Signed-off-by: Dave Airlie --- include/drm/drm_edid.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 39e2cc5..5881fad 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -28,6 +28,12 @@ #define EDID_LENGTH 128 #define DDC_ADDR 0x50 +#define CEA_EXT 0x02 +#define VTB_EXT 0x10 +#define DI_EXT 0x40 +#define LS_EXT 0x50 +#define MI_EXT 0x60 + struct est_timings { u8 t1; u8 t2; -- cgit v1.1 From 7203425a943eb3e189ba6b512827e0deb5f23872 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Tue, 3 Aug 2010 01:33:19 +0100 Subject: drm: expand gamma_set Expand the crtc_gamma_set function to accept a starting offset. The reason for this is to eventually use this function for setcolreg from drm_fb_helper.c. The fbdev colormap function can start at any offset in the color map. Signed-by: James Simmons Signed-off-by: Dave Airlie --- include/drm/drm_crtc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 606eb93..692cc55 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -310,7 +310,7 @@ struct drm_crtc_funcs { /* Set gamma on the CRTC */ void (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, - uint32_t size); + uint32_t start, uint32_t size); /* Object destroy routine */ void (*destroy)(struct drm_crtc *crtc); -- cgit v1.1 From 7ed24e8da75615418cbf3417e421053e53a5f5b3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 9 Aug 2010 13:40:03 +0000 Subject: etherdevice.h: fix kernel-doc typo Fix etherdevice.h parameter name typo in kernel-doc: Warning(include/linux/etherdevice.h:138): No description found for parameter 'hwaddr' Warning(include/linux/etherdevice.h:138): Excess function parameter 'addr' description in 'dev_hw_addr_random' Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- include/linux/etherdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 848480b..2308fbb 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -129,7 +129,7 @@ static inline void random_ether_addr(u8 *addr) /** * dev_hw_addr_random - Create random MAC and set device flag * @dev: pointer to net_device structure - * @addr: Pointer to a six-byte array containing the Ethernet address + * @hwaddr: Pointer to a six-byte array containing the Ethernet address * * Generate random MAC to be used by a device and set addr_assign_type * so the state can be read by sysfs and be used by udev. -- cgit v1.1 From 53c3fa206415d8a3f8b2a4f77689ea044c4a9c65 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 9 Aug 2010 13:41:07 +0000 Subject: net/sock.h: add missing kernel-doc notation Add missing kernel-doc notation to struct sock: Warning(include/net/sock.h:324): No description found for parameter 'sk_peer_pid' Warning(include/net/sock.h:324): No description found for parameter 'sk_peer_cred' Warning(include/net/sock.h:324): No description found for parameter 'sk_classid' Warning(include/net/sock.h:324): Excess struct/union/enum/typedef member 'sk_peercred' description in 'sock' Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- include/net/sock.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index a441c9c..ac53bfb 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -195,7 +195,8 @@ struct sock_common { * @sk_priority: %SO_PRIORITY setting * @sk_type: socket type (%SOCK_STREAM, etc) * @sk_protocol: which protocol this socket belongs in this network family - * @sk_peercred: %SO_PEERCRED setting + * @sk_peer_pid: &struct pid for this socket's peer + * @sk_peer_cred: %SO_PEERCRED setting * @sk_rcvlowat: %SO_RCVLOWAT setting * @sk_rcvtimeo: %SO_RCVTIMEO setting * @sk_sndtimeo: %SO_SNDTIMEO setting @@ -211,6 +212,7 @@ struct sock_common { * @sk_send_head: front of stuff to transmit * @sk_security: used by security modules * @sk_mark: generic packet mark + * @sk_classid: this socket's cgroup classid * @sk_write_pending: a write to stream socket waits to start * @sk_state_change: callback to indicate change in the state of the sock * @sk_data_ready: callback to indicate there is data to be processed -- cgit v1.1 From fa235562fbde8703aabeeedfa0772f08608d1542 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 5 Aug 2010 15:54:20 -0700 Subject: Bluetooth: Change default L2CAP ERTM retransmit timeout The L2CAP specification requires that the ERTM retransmit timeout be at least 2 seconds for BR/EDR connections. Signed-off-by: Mat Martineau Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 636724b..16e412f 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -33,7 +33,7 @@ #define L2CAP_DEFAULT_FLUSH_TO 0xffff #define L2CAP_DEFAULT_TX_WINDOW 63 #define L2CAP_DEFAULT_MAX_TX 3 -#define L2CAP_DEFAULT_RETRANS_TO 1000 /* 1 second */ +#define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */ #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ #define L2CAP_DEFAULT_MAX_PDU_SIZE 672 #define L2CAP_DEFAULT_ACK_TO 200 -- cgit v1.1 From db12d647ccc971ed120199dc7ea5be2b5887d328 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 5 Aug 2010 15:54:27 -0700 Subject: Bluetooth: Use 3-DH5 payload size for default ERTM max PDU size The previous value of 672 for L2CAP_DEFAULT_MAX_PDU_SIZE is based on the default L2CAP MTU. That default MTU is calculated from the size of two DH5 packets, minus ACL and L2CAP b-frame header overhead. ERTM is used with newer basebands that typically support larger 3-DH5 packets, and i-frames and s-frames have more header overhead. With clean RF conditions, basebands will typically attempt to use 1021-byte 3-DH5 packets for maximum throughput. Adjusting for 2 bytes of ACL headers plus 10 bytes of worst-case L2CAP headers yields 1009 bytes of payload. This PDU size imposes less overhead for header bytes and gives the baseband the option to choose 3-DH5 packets, but is small enough for ERTM traffic to interleave well with other L2CAP or SCO data. 672-byte payloads do not allow the most efficient over-the-air packet choice, and cannot achieve maximum throughput over BR/EDR. Signed-off-by: Mat Martineau Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 16e412f..6c24144 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -35,7 +35,7 @@ #define L2CAP_DEFAULT_MAX_TX 3 #define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */ #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ -#define L2CAP_DEFAULT_MAX_PDU_SIZE 672 +#define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */ #define L2CAP_DEFAULT_ACK_TO 200 #define L2CAP_LOCAL_BUSY_TRIES 12 -- cgit v1.1 From 969a6e521730153380ad7781095f503c040b684c Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 10 Aug 2010 16:24:41 -0700 Subject: net: make netpoll_rx return bool for !CONFIG_NETPOLL "netpoll: Use 'bool' for netpoll_rx() return type." missed the case when CONFIG_NETPOLL is disabled. Signed-off-by: John W. Linville Signed-off-by: David S. Miller --- include/linux/netpoll.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 413742c..791d510 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -122,7 +122,7 @@ static inline int netpoll_tx_running(struct net_device *dev) } #else -static inline int netpoll_rx(struct sk_buff *skb) +static inline bool netpoll_rx(struct sk_buff *skb) { return 0; } -- cgit v1.1 From 496ee9b8f349a8ae2065114c414a47e89bdeb930 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 22 Jul 2010 03:11:48 +0200 Subject: V7: Adjust sanity checks for some volumes Newly mkfs-ed filesystems from Seventh Edition have last modification time set to zero, but are otherwise perfectly valid. Also, tighten up other sanity checks to filter out most filesystems with different bytesex than we're using. Cc: Christoph Hellwig Signed-off-by: Lubomir Rintel Signed-off-by: Al Viro --- include/linux/sysv_fs.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/linux/sysv_fs.h b/include/linux/sysv_fs.h index 9641130..e47d6d9 100644 --- a/include/linux/sysv_fs.h +++ b/include/linux/sysv_fs.h @@ -148,6 +148,17 @@ struct v7_super_block { char s_fname[6]; /* file system name */ char s_fpack[6]; /* file system pack name */ }; +/* Constants to aid sanity checking */ +/* This is not a hard limit, nor enforced by v7 kernel. It's actually just + * the limit used by Seventh Edition's ls, though is high enough to assume + * that no reasonable file system would have that much entries in root + * directory. Thus, if we see anything higher, we just probably got the + * endiannes wrong. */ +#define V7_NFILES 1024 +/* The disk addresses are three-byte (despite direct block addresses being + * aligned word-wise in inode). If the most significant byte is non-zero, + * something is most likely wrong (not a filesystem, bad bytesex). */ +#define V7_MAXSIZE 0x00ffffff /* Coherent super-block data on disk */ #define COH_NICINOD 100 /* number of inode cache entries */ -- cgit v1.1 From f7ad3c6be90809b53b7f0ae9d4eaa45ce2564a79 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 10 Aug 2010 11:41:36 +0200 Subject: vfs: add helpers to get root and pwd Add three helpers that retrieve a refcounted copy of the root and cwd from the supplied fs_struct. get_fs_root() get_fs_pwd() get_fs_root_and_pwd() Signed-off-by: Miklos Szeredi Signed-off-by: Al Viro --- include/linux/fs_struct.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'include') diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index 78a05bf..eca3d52 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h @@ -21,4 +21,31 @@ extern void free_fs_struct(struct fs_struct *); extern void daemonize_fs_struct(void); extern int unshare_fs_struct(void); +static inline void get_fs_root(struct fs_struct *fs, struct path *root) +{ + read_lock(&fs->lock); + *root = fs->root; + path_get(root); + read_unlock(&fs->lock); +} + +static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd) +{ + read_lock(&fs->lock); + *pwd = fs->pwd; + path_get(pwd); + read_unlock(&fs->lock); +} + +static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root, + struct path *pwd) +{ + read_lock(&fs->lock); + *root = fs->root; + path_get(root); + *pwd = fs->pwd; + path_get(pwd); + read_unlock(&fs->lock); +} + #endif /* _LINUX_FS_STRUCT_H */ -- cgit v1.1 From 8df9d1a4142311c084ffeeacb67cd34d190eff74 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 10 Aug 2010 11:41:41 +0200 Subject: vfs: show unreachable paths in getcwd and proc Prepend "(unreachable)" to path strings if the path is not reachable from the current root. Two places updated are - the return string from getcwd() - and symlinks under /proc/$PID. Other uses of d_path() are left unchanged (we know that some old software crashes if /proc/mounts is changed). Signed-off-by: Miklos Szeredi Signed-off-by: Al Viro --- include/linux/dcache.h | 1 + include/linux/path.h | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/dcache.h b/include/linux/dcache.h index d23be03..6a4aea3 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -315,6 +315,7 @@ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); extern char *__d_path(const struct path *path, struct path *root, char *, int); extern char *d_path(const struct path *, char *, int); +extern char *d_path_with_unreachable(const struct path *, char *, int); extern char *__dentry_path(struct dentry *, char *, int); extern char *dentry_path(struct dentry *, char *, int); diff --git a/include/linux/path.h b/include/linux/path.h index 915e0c3..edc98de 100644 --- a/include/linux/path.h +++ b/include/linux/path.h @@ -12,4 +12,9 @@ struct path { extern void path_get(struct path *); extern void path_put(struct path *); +static inline int path_equal(const struct path *path1, const struct path *path2) +{ + return path1->mnt == path2->mnt && path1->dentry == path2->dentry; +} + #endif /* _LINUX_PATH_H */ -- cgit v1.1 From 532490f0a5350fd92d838b7430a4c846bc8eac3f Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 2 Aug 2010 13:46:56 +0200 Subject: vfs: remove unused MNT_STRICTATIME Commit d0adde574b8487ef30f69e2d08bba769e4be513f added MNT_STRICTATIME but it isn't actually used (MS_STRICTATIME clears MNT_RELATIME and MNT_NOATIME rather than setting any mount flag). Signed-off-by: Miklos Szeredi Signed-off-by: Al Viro --- include/linux/mount.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/mount.h b/include/linux/mount.h index 907210b..5e7a594 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -27,7 +27,6 @@ struct mnt_namespace; #define MNT_NODIRATIME 0x10 #define MNT_RELATIME 0x20 #define MNT_READONLY 0x40 /* does the user want this to be r/o? */ -#define MNT_STRICTATIME 0x80 #define MNT_SHRINKABLE 0x100 #define MNT_WRITE_HOLD 0x200 -- cgit v1.1 From 8edf344c66a3f214d709dad1421c29d678915b3f Mon Sep 17 00:00:00 2001 From: Naoya Horiguchi Date: Fri, 28 May 2010 09:29:15 +0900 Subject: hugetlb: move definition of is_vm_hugetlb_page() to hugepage_inline.h is_vm_hugetlb_page() is a widely used inline function to insert hooks into hugetlb code. But we can't use it in pagemap.h because of circular dependency of the header files. This patch removes this limitation. Acked-by: Mel Gorman Acked-by: Fengguang Wu Signed-off-by: Naoya Horiguchi Signed-off-by: Andi Kleen --- include/linux/hugetlb.h | 11 +---------- include/linux/hugetlb_inline.h | 22 ++++++++++++++++++++++ include/linux/pagemap.h | 1 + 3 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 include/linux/hugetlb_inline.h (limited to 'include') diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 78b4bc6..d47a7c4 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -2,6 +2,7 @@ #define _LINUX_HUGETLB_H #include +#include struct ctl_table; struct user_struct; @@ -14,11 +15,6 @@ struct user_struct; int PageHuge(struct page *page); -static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) -{ - return vma->vm_flags & VM_HUGETLB; -} - void reset_vma_resv_huge_pages(struct vm_area_struct *vma); int hugetlb_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); int hugetlb_overcommit_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); @@ -77,11 +73,6 @@ static inline int PageHuge(struct page *page) return 0; } -static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) -{ - return 0; -} - static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma) { } diff --git a/include/linux/hugetlb_inline.h b/include/linux/hugetlb_inline.h new file mode 100644 index 0000000..cf00b6d --- /dev/null +++ b/include/linux/hugetlb_inline.h @@ -0,0 +1,22 @@ +#ifndef _LINUX_HUGETLB_INLINE_H +#define _LINUX_HUGETLB_INLINE_H 1 + +#ifdef CONFIG_HUGETLBFS + +#include + +static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) +{ + return vma->vm_flags & VM_HUGETLB; +} + +#else + +static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) +{ + return 0; +} + +#endif + +#endif diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 3c62ed4..b2bd2ba 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -13,6 +13,7 @@ #include #include #include /* for in_interrupt() */ +#include /* * Bits in mapping->flags. The lower __GFP_BITS_SHIFT bits are the page -- cgit v1.1 From 0fe6e20b9c4c53b3e97096ee73a0857f60aad43f Mon Sep 17 00:00:00 2001 From: Naoya Horiguchi Date: Fri, 28 May 2010 09:29:16 +0900 Subject: hugetlb, rmap: add reverse mapping for hugepage This patch adds reverse mapping feature for hugepage by introducing mapcount for shared/private-mapped hugepage and anon_vma for private-mapped hugepage. While hugepage is not currently swappable, reverse mapping can be useful for memory error handler. Without this patch, memory error handler cannot identify processes using the bad hugepage nor unmap it from them. That is: - for shared hugepage: we can collect processes using a hugepage through pagecache, but can not unmap the hugepage because of the lack of mapcount. - for privately mapped hugepage: we can neither collect processes nor unmap the hugepage. This patch solves these problems. This patch include the bug fix given by commit 23be7468e8, so reverts it. Dependency: "hugetlb: move definition of is_vm_hugetlb_page() to hugepage_inline.h" ChangeLog since May 24. - create hugetlb_inline.h and move is_vm_hugetlb_index() in it. - move functions setting up anon_vma for hugepage into mm/rmap.c. ChangeLog since May 13. - rebased to 2.6.34 - fix logic error (in case that private mapping and shared mapping coexist) - move is_vm_hugetlb_page() into include/linux/mm.h to use this function from linear_page_index() - define and use linear_hugepage_index() instead of compound_order() - use page_move_anon_rmap() in hugetlb_cow() - copy exclusive switch of __set_page_anon_rmap() into hugepage counterpart. - revert commit 24be7468 completely Signed-off-by: Naoya Horiguchi Cc: Andi Kleen Cc: Andrew Morton Cc: Mel Gorman Cc: Andrea Arcangeli Cc: Larry Woodman Cc: Lee Schermerhorn Acked-by: Fengguang Wu Acked-by: Mel Gorman Signed-off-by: Andi Kleen --- include/linux/hugetlb.h | 1 + include/linux/pagemap.h | 8 +++++++- include/linux/poison.h | 9 --------- include/linux/rmap.h | 5 +++++ 4 files changed, 13 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index d47a7c4..e688fd8 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -99,6 +99,7 @@ static inline void hugetlb_report_meminfo(struct seq_file *m) #define is_hugepage_only_range(mm, addr, len) 0 #define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) ({BUG(); 0; }) #define hugetlb_fault(mm, vma, addr, flags) ({ BUG(); 0; }) +#define huge_pte_offset(mm, address) 0 #define hugetlb_change_protection(vma, address, end, newprot) diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index b2bd2ba..a547d96 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -282,10 +282,16 @@ static inline loff_t page_offset(struct page *page) return ((loff_t)page->index) << PAGE_CACHE_SHIFT; } +extern pgoff_t linear_hugepage_index(struct vm_area_struct *vma, + unsigned long address); + static inline pgoff_t linear_page_index(struct vm_area_struct *vma, unsigned long address) { - pgoff_t pgoff = (address - vma->vm_start) >> PAGE_SHIFT; + pgoff_t pgoff; + if (unlikely(is_vm_hugetlb_page(vma))) + return linear_hugepage_index(vma, address); + pgoff = (address - vma->vm_start) >> PAGE_SHIFT; pgoff += vma->vm_pgoff; return pgoff >> (PAGE_CACHE_SHIFT - PAGE_SHIFT); } diff --git a/include/linux/poison.h b/include/linux/poison.h index 34066ff..2110a81 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -48,15 +48,6 @@ #define POISON_FREE 0x6b /* for use-after-free poisoning */ #define POISON_END 0xa5 /* end-byte of poisoning */ -/********** mm/hugetlb.c **********/ -/* - * Private mappings of hugetlb pages use this poisoned value for - * page->mapping. The core VM should not be doing anything with this mapping - * but futex requires the existence of some page->mapping value even though it - * is unused if PAGE_MAPPING_ANON is set. - */ -#define HUGETLB_POISON ((void *)(0x00300300 + POISON_POINTER_DELTA + PAGE_MAPPING_ANON)) - /********** arch/$ARCH/mm/init.c **********/ #define POISON_FREE_INITMEM 0xcc diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 7721674..9d50e7e 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -140,6 +140,11 @@ void page_add_new_anon_rmap(struct page *, struct vm_area_struct *, unsigned lon void page_add_file_rmap(struct page *); void page_remove_rmap(struct page *); +void hugepage_add_anon_rmap(struct page *, struct vm_area_struct *, + unsigned long); +void hugepage_add_new_anon_rmap(struct page *, struct vm_area_struct *, + unsigned long); + static inline void page_dup_rmap(struct page *page) { atomic_inc(&page->_mapcount); -- cgit v1.1 From 93f70f900da36fbc19c13c2aa04b2e468c8d00fb Mon Sep 17 00:00:00 2001 From: Naoya Horiguchi Date: Fri, 28 May 2010 09:29:20 +0900 Subject: HWPOISON, hugetlb: isolate corrupted hugepage If error hugepage is not in-use, we can fully recovery from error by dequeuing it from freelist, so return RECOVERY. Otherwise whether or not we can recovery depends on user processes, so return DELAYED. Dependency: "HWPOISON, hugetlb: enable error handling path for hugepage" Signed-off-by: Naoya Horiguchi Cc: Andrew Morton Acked-by: Fengguang Wu Signed-off-by: Andi Kleen --- include/linux/hugetlb.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index e688fd8..f479700 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -43,6 +43,7 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to, struct vm_area_struct *vma, int acctflags); void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed); +void __isolate_hwpoisoned_huge_page(struct page *page); extern unsigned long hugepages_treat_as_movable; extern const unsigned long hugetlb_zero, hugetlb_infinity; @@ -100,6 +101,7 @@ static inline void hugetlb_report_meminfo(struct seq_file *m) #define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) ({BUG(); 0; }) #define hugetlb_fault(mm, vma, addr, flags) ({ BUG(); 0; }) #define huge_pte_offset(mm, address) 0 +#define __isolate_hwpoisoned_huge_page(page) 0 #define hugetlb_change_protection(vma, address, end, newprot) -- cgit v1.1 From e3390f67a7267daa227380b6f1bbf13c7ddd4aff Mon Sep 17 00:00:00 2001 From: Naoya Horiguchi Date: Tue, 15 Jun 2010 13:18:13 +0900 Subject: hwpoison: rename CONFIG CONFIG_HUGETLBFS controls hugetlbfs interface code. OTOH, CONFIG_HUGETLB_PAGE controls hugepage management code. So we should use CONFIG_HUGETLB_PAGE here. Signed-off-by: Naoya Horiguchi Signed-off-by: Andi Kleen --- include/linux/hugetlb_inline.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/hugetlb_inline.h b/include/linux/hugetlb_inline.h index cf00b6d..6931489 100644 --- a/include/linux/hugetlb_inline.h +++ b/include/linux/hugetlb_inline.h @@ -1,7 +1,7 @@ #ifndef _LINUX_HUGETLB_INLINE_H -#define _LINUX_HUGETLB_INLINE_H 1 +#define _LINUX_HUGETLB_INLINE_H -#ifdef CONFIG_HUGETLBFS +#ifdef CONFIG_HUGETLB_PAGE #include -- cgit v1.1 From 156f252857dfd81f03d77d09e33b5f7d2b113e2b Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 16 Jun 2010 09:04:16 +0200 Subject: drivers: regulator: add Maxim 8998 driver Acked-by: Mark Brown This patch adds voltage regulator driver for Maxim 8998 chip. This chip is used on Samsung Aquila and GONI boards and provides following functionalities: - 4 BUCK voltage converters, 17 LDO power regulators and 5 other power controllers - battery charger This patch adds basic driver for voltage regulators and MAX 8998 MFD core. Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Acked-by: Samuel Ortiz Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- include/linux/mfd/max8998-private.h | 112 ++++++++++++++++++++++++++++++++++++ include/linux/mfd/max8998.h | 78 +++++++++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 include/linux/mfd/max8998-private.h create mode 100644 include/linux/mfd/max8998.h (limited to 'include') diff --git a/include/linux/mfd/max8998-private.h b/include/linux/mfd/max8998-private.h new file mode 100644 index 0000000..6dc75b3 --- /dev/null +++ b/include/linux/mfd/max8998-private.h @@ -0,0 +1,112 @@ +/* + * max8698.h - Voltage regulator driver for the Maxim 8998 + * + * Copyright (C) 2009-2010 Samsung Electrnoics + * Kyungmin Park + * Marek Szyprowski + * + * 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_MFD_MAX8998_PRIV_H +#define __LINUX_MFD_MAX8998_PRIV_H + +/* MAX 8998 registers */ +enum { + MAX8998_REG_IRQ1, + MAX8998_REG_IRQ2, + MAX8998_REG_IRQ3, + MAX8998_REG_IRQ4, + MAX8998_REG_IRQM1, + MAX8998_REG_IRQM2, + MAX8998_REG_IRQM3, + MAX8998_REG_IRQM4, + MAX8998_REG_STATUS1, + MAX8998_REG_STATUS2, + MAX8998_REG_STATUSM1, + MAX8998_REG_STATUSM2, + MAX8998_REG_CHGR1, + MAX8998_REG_CHGR2, + MAX8998_REG_LDO_ACTIVE_DISCHARGE1, + MAX8998_REG_LDO_ACTIVE_DISCHARGE2, + MAX8998_REG_BUCK_ACTIVE_DISCHARGE3, + MAX8998_REG_ONOFF1, + MAX8998_REG_ONOFF2, + MAX8998_REG_ONOFF3, + MAX8998_REG_ONOFF4, + MAX8998_REG_BUCK1_DVSARM1, + MAX8998_REG_BUCK1_DVSARM2, + MAX8998_REG_BUCK1_DVSARM3, + MAX8998_REG_BUCK1_DVSARM4, + MAX8998_REG_BUCK2_DVSINT1, + MAX8998_REG_BUCK2_DVSINT2, + MAX8998_REG_BUCK3, + MAX8998_REG_BUCK4, + MAX8998_REG_LDO2_LDO3, + MAX8998_REG_LDO4, + MAX8998_REG_LDO5, + MAX8998_REG_LDO6, + MAX8998_REG_LDO7, + MAX8998_REG_LDO8_LDO9, + MAX8998_REG_LDO10_LDO11, + MAX8998_REG_LDO12, + MAX8998_REG_LDO13, + MAX8998_REG_LDO14, + MAX8998_REG_LDO15, + MAX8998_REG_LDO16, + MAX8998_REG_LDO17, + MAX8998_REG_BKCHR, + MAX8998_REG_LBCNFG1, + MAX8998_REG_LBCNFG2, +}; + +/** + * struct max8998_dev - max8998 master device for sub-drivers + * @dev: master device of the chip (can be used to access platform data) + * @i2c_client: i2c client private data + * @dev_read(): chip register read function + * @dev_write(): chip register write function + * @dev_update(): chip register update function + * @iolock: mutex for serializing io access + */ + +struct max8998_dev { + struct device *dev; + struct i2c_client *i2c_client; + int (*dev_read)(struct max8998_dev *max8998, u8 reg, u8 *dest); + int (*dev_write)(struct max8998_dev *max8998, u8 reg, u8 val); + int (*dev_update)(struct max8998_dev *max8998, u8 reg, u8 val, u8 mask); + struct mutex iolock; +}; + +static inline int max8998_read_reg(struct max8998_dev *max8998, u8 reg, + u8 *value) +{ + return max8998->dev_read(max8998, reg, value); +} + +static inline int max8998_write_reg(struct max8998_dev *max8998, u8 reg, + u8 value) +{ + return max8998->dev_write(max8998, reg, value); +} + +static inline int max8998_update_reg(struct max8998_dev *max8998, u8 reg, + u8 value, u8 mask) +{ + return max8998->dev_update(max8998, reg, value, mask); +} + +#endif /* __LINUX_MFD_MAX8998_PRIV_H */ diff --git a/include/linux/mfd/max8998.h b/include/linux/mfd/max8998.h new file mode 100644 index 0000000..1d3601a --- /dev/null +++ b/include/linux/mfd/max8998.h @@ -0,0 +1,78 @@ +/* + * max8698.h - Voltage regulator driver for the Maxim 8998 + * + * Copyright (C) 2009-2010 Samsung Electrnoics + * Kyungmin Park + * Marek Szyprowski + * + * 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_MFD_MAX8998_H +#define __LINUX_MFD_MAX8998_H + +#include + +/* MAX 8998 regulator ids */ +enum { + MAX8998_LDO2 = 2, + MAX8998_LDO3, + MAX8998_LDO4, + MAX8998_LDO5, + MAX8998_LDO6, + MAX8998_LDO7, + MAX8998_LDO8, + MAX8998_LDO9, + MAX8998_LDO10, + MAX8998_LDO11, + MAX8998_LDO12, + MAX8998_LDO13, + MAX8998_LDO14, + MAX8998_LDO15, + MAX8998_LDO16, + MAX8998_LDO17, + MAX8998_BUCK1, + MAX8998_BUCK2, + MAX8998_BUCK3, + MAX8998_BUCK4, + MAX8998_EN32KHZ_AP, + MAX8998_EN32KHZ_CP, + MAX8998_ENVICHG, + MAX8998_ESAFEOUT1, + MAX8998_ESAFEOUT2, +}; + +/** + * max8998_regulator_data - regulator data + * @id: regulator id + * @initdata: regulator init data (contraints, supplies, ...) + */ +struct max8998_regulator_data { + int id; + struct regulator_init_data *initdata; +}; + +/** + * struct max8998_board - packages regulator init data + * @num_regulators: number of regultors used + * @regulators: array of defined regulators + */ + +struct max8998_platform_data { + int num_regulators; + struct max8998_regulator_data *regulators; +}; + +#endif /* __LINUX_MFD_MAX8998_H */ -- cgit v1.1 From 549931f99e030d63a437c23943fd8dc9b7c0e41c Mon Sep 17 00:00:00 2001 From: Sundar R Iyer Date: Tue, 13 Jul 2010 11:51:28 +0530 Subject: ab8500-mfd: add regulator support to ab8500 mfd device Acked-by: Linus Walleij Acked-By: Mattias Wallin Acked-By: Bengt JONSSON Signed-off-by: Sundar R Iyer Acked-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/ab8500.h | 6 ++++++ include/linux/regulator/ab8500.h | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 include/linux/regulator/ab8500.h (limited to 'include') diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h index b63ff3b..f5cec45 100644 --- a/include/linux/mfd/ab8500.h +++ b/include/linux/mfd/ab8500.h @@ -76,6 +76,8 @@ #define AB8500_NR_IRQS 104 #define AB8500_NUM_IRQ_REGS 13 +#define AB8500_NUM_REGULATORS 15 + /** * struct ab8500 - ab8500 internal structure * @dev: parent device @@ -108,14 +110,18 @@ struct ab8500 { u8 oldmask[AB8500_NUM_IRQ_REGS]; }; +struct regulator_init_data; + /** * struct ab8500_platform_data - AB8500 platform data * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used * @init: board-specific initialization after detection of ab8500 + * @regulator: machine-specific constraints for regulators */ struct ab8500_platform_data { int irq_base; void (*init) (struct ab8500 *); + struct regulator_init_data *regulator[AB8500_NUM_REGULATORS]; }; extern int ab8500_write(struct ab8500 *a8500, u16 addr, u8 data); diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h new file mode 100644 index 0000000..f509877 --- /dev/null +++ b/include/linux/regulator/ab8500.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * + * Author: Sundar Iyer for ST-Ericsson + * + */ + +#ifndef __LINUX_MFD_AB8500_REGULATOR_H +#define __LINUX_MFD_AB8500_REGULATOR_H + +/* AB8500 regulators */ +#define AB8500_LDO_AUX1 0 +#define AB8500_LDO_AUX2 1 +#define AB8500_LDO_AUX3 2 +#define AB8500_LDO_INTCORE 3 +#define AB8500_LDO_TVOUT 4 +#define AB8500_LDO_AUDIO 5 +#define AB8500_LDO_ANAMIC1 6 +#define AB8500_LDO_ANAMIC2 7 +#define AB8500_LDO_DMIC 8 +#define AB8500_LDO_ANA 9 + +#endif -- cgit v1.1 From 9bbb9e5a33109b2832e2e63dcc7a132924ab374b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Aug 2010 23:04:12 -0600 Subject: param: use ops in struct kernel_param, rather than get and set fns directly This is more kernel-ish, saves some space, and also allows us to expand the ops without breaking all the callers who are happy for the new members to be NULL. The few places which defined their own param types are changed to the new scheme (more which crept in recently fixed in following patches). Since we're touching them anyway, we change get() and set() to take a const struct kernel_param (which they really are). This causes some harmless warnings until we fix them (in following patches). To reduce churn, module_param_call creates the ops struct so the callers don't have to change (and casts the functions to reduce warnings). The modern version which takes an ops struct is called module_param_cb. Signed-off-by: Rusty Russell Reviewed-by: Takashi Iwai Tested-by: Phil Carmody Cc: "David S. Miller" Cc: Ville Syrjala Cc: Dmitry Torokhov Cc: Alessandro Rubini Cc: Michal Januszewski Cc: Trond Myklebust Cc: "J. Bruce Fields" Cc: Neil Brown Cc: linux-kernel@vger.kernel.org Cc: linux-input@vger.kernel.org Cc: linux-fbdev-devel@lists.sourceforge.net Cc: linux-nfs@vger.kernel.org Cc: netdev@vger.kernel.org --- include/linux/moduleparam.h | 123 +++++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 48 deletions(-) (limited to 'include') diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 82a9124..02e5090 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -31,20 +31,21 @@ static const char __module_cat(name,__LINE__)[] \ struct kernel_param; -/* Returns 0, or -errno. arg is in kp->arg. */ -typedef int (*param_set_fn)(const char *val, struct kernel_param *kp); -/* Returns length written or -errno. Buffer is 4k (ie. be short!) */ -typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp); +struct kernel_param_ops { + /* 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!) */ + int (*get)(char *buffer, const struct kernel_param *kp); +}; /* Flag bits for kernel_param.flags */ #define KPARAM_ISBOOL 2 struct kernel_param { const char *name; + const struct kernel_param_ops *ops; u16 perm; u16 flags; - param_set_fn set; - param_get_fn get; union { void *arg; const struct kparam_string *str; @@ -63,8 +64,7 @@ struct kparam_array { unsigned int max; unsigned int *num; - param_set_fn set; - param_get_fn get; + const struct kernel_param_ops *ops; unsigned int elemsize; void *elem; }; @@ -83,7 +83,7 @@ struct kparam_array parameters. perm sets the visibility in sysfs: 000 means it's not there, read bits mean it's readable, write bits mean it's writable. */ -#define __module_param_call(prefix, name, set, get, arg, isbool, perm) \ +#define __module_param_call(prefix, name, ops, arg, isbool, perm) \ /* Default value instead of permissions? */ \ static int __param_perm_check_##name __attribute__((unused)) = \ BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ @@ -92,20 +92,37 @@ struct kparam_array static struct kernel_param __moduleparam_const __param_##name \ __used \ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ - = { __param_str_##name, perm, isbool ? KPARAM_ISBOOL : 0, \ - set, get, { arg } } + = { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \ + { arg } } + +/* 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 }; \ + __module_param_call(MODULE_PARAM_PREFIX, \ + name, &__param_ops_##name, arg, \ + __same_type(*(arg), bool), \ + (perm) + sizeof(__check_old_set_param(set))*0) + +/* We don't get oldget: it's often a new-style param_get_uint, etc. */ +static inline int +__check_old_set_param(int (*oldset)(const char *, struct kernel_param *)) +{ + return 0; +} -#define module_param_call(name, set, get, arg, perm) \ +#define module_param_cb(name, ops, arg, perm) \ __module_param_call(MODULE_PARAM_PREFIX, \ - name, set, get, arg, \ - __same_type(*(arg), bool), perm) + name, ops, arg, __same_type(*(arg), bool), perm) -/* Helper functions: type is byte, short, ushort, int, uint, long, - ulong, charp, bool or invbool, or XXX if you define param_get_XXX, - param_set_XXX and param_check_XXX. */ +/* + * Helper functions: type is byte, short, ushort, int, uint, long, + * ulong, charp, bool or invbool, or XXX if you define param_ops_XXX + * and param_check_XXX. + */ #define module_param_named(name, value, type, perm) \ param_check_##type(name, &(value)); \ - module_param_call(name, param_set_##type, param_get_##type, &value, perm); \ + module_param_cb(name, ¶m_ops_##type, &value, perm); \ __MODULE_PARM_TYPE(name, #type) #define module_param(name, type, perm) \ @@ -126,7 +143,7 @@ struct kparam_array */ #define core_param(name, var, type, perm) \ param_check_##type(name, &(var)); \ - __module_param_call("", name, param_set_##type, param_get_##type, \ + __module_param_call("", name, ¶m_ops_##type, \ &var, __same_type(var, bool), perm) #endif /* !MODULE */ @@ -135,7 +152,7 @@ struct kparam_array static const struct kparam_string __param_string_##name \ = { len, string }; \ __module_param_call(MODULE_PARAM_PREFIX, name, \ - param_set_copystring, param_get_string, \ + ¶m_ops_string, \ .str = &__param_string_##name, 0, perm); \ __MODULE_PARM_TYPE(name, "string") @@ -162,41 +179,50 @@ static inline void destroy_params(const struct kernel_param *params, #define __param_check(name, p, type) \ static inline type *__check_##name(void) { return(p); } -extern int param_set_byte(const char *val, struct kernel_param *kp); -extern int param_get_byte(char *buffer, struct kernel_param *kp); +extern struct kernel_param_ops param_ops_byte; +extern int param_set_byte(const char *val, const struct kernel_param *kp); +extern int param_get_byte(char *buffer, const struct kernel_param *kp); #define param_check_byte(name, p) __param_check(name, p, unsigned char) -extern int param_set_short(const char *val, struct kernel_param *kp); -extern int param_get_short(char *buffer, struct kernel_param *kp); +extern struct kernel_param_ops param_ops_short; +extern int param_set_short(const char *val, const struct kernel_param *kp); +extern int param_get_short(char *buffer, const struct kernel_param *kp); #define param_check_short(name, p) __param_check(name, p, short) -extern int param_set_ushort(const char *val, struct kernel_param *kp); -extern int param_get_ushort(char *buffer, struct kernel_param *kp); +extern struct kernel_param_ops param_ops_ushort; +extern int param_set_ushort(const char *val, const struct kernel_param *kp); +extern int param_get_ushort(char *buffer, const struct kernel_param *kp); #define param_check_ushort(name, p) __param_check(name, p, unsigned short) -extern int param_set_int(const char *val, struct kernel_param *kp); -extern int param_get_int(char *buffer, struct kernel_param *kp); +extern struct kernel_param_ops param_ops_int; +extern int param_set_int(const char *val, const struct kernel_param *kp); +extern int param_get_int(char *buffer, const struct kernel_param *kp); #define param_check_int(name, p) __param_check(name, p, int) -extern int param_set_uint(const char *val, struct kernel_param *kp); -extern int param_get_uint(char *buffer, struct kernel_param *kp); +extern struct kernel_param_ops param_ops_uint; +extern int param_set_uint(const char *val, const struct kernel_param *kp); +extern int param_get_uint(char *buffer, const struct kernel_param *kp); #define param_check_uint(name, p) __param_check(name, p, unsigned int) -extern int param_set_long(const char *val, struct kernel_param *kp); -extern int param_get_long(char *buffer, struct kernel_param *kp); +extern struct kernel_param_ops param_ops_long; +extern int param_set_long(const char *val, const struct kernel_param *kp); +extern int param_get_long(char *buffer, const struct kernel_param *kp); #define param_check_long(name, p) __param_check(name, p, long) -extern int param_set_ulong(const char *val, struct kernel_param *kp); -extern int param_get_ulong(char *buffer, struct kernel_param *kp); +extern struct kernel_param_ops param_ops_ulong; +extern int param_set_ulong(const char *val, const struct kernel_param *kp); +extern int param_get_ulong(char *buffer, const struct kernel_param *kp); #define param_check_ulong(name, p) __param_check(name, p, unsigned long) -extern int param_set_charp(const char *val, struct kernel_param *kp); -extern int param_get_charp(char *buffer, struct kernel_param *kp); +extern struct kernel_param_ops param_ops_charp; +extern int param_set_charp(const char *val, const struct kernel_param *kp); +extern int param_get_charp(char *buffer, const struct kernel_param *kp); #define param_check_charp(name, p) __param_check(name, p, char *) /* For historical reasons "bool" parameters can be (unsigned) "int". */ -extern int param_set_bool(const char *val, struct kernel_param *kp); -extern int param_get_bool(char *buffer, struct kernel_param *kp); +extern struct kernel_param_ops param_ops_bool; +extern int param_set_bool(const char *val, const struct kernel_param *kp); +extern int param_get_bool(char *buffer, const struct kernel_param *kp); #define param_check_bool(name, p) \ static inline void __check_##name(void) \ { \ @@ -205,17 +231,18 @@ extern int param_get_bool(char *buffer, struct kernel_param *kp); !__same_type(*(p), int)); \ } -extern int param_set_invbool(const char *val, struct kernel_param *kp); -extern int param_get_invbool(char *buffer, struct kernel_param *kp); +extern struct kernel_param_ops param_ops_invbool; +extern int param_set_invbool(const char *val, const struct kernel_param *kp); +extern int param_get_invbool(char *buffer, const struct kernel_param *kp); #define param_check_invbool(name, p) __param_check(name, p, bool) /* Comma-separated array: *nump is set to number they actually specified. */ #define module_param_array_named(name, array, type, nump, perm) \ static const struct kparam_array __param_arr_##name \ - = { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type,\ + = { ARRAY_SIZE(array), nump, ¶m_ops_##type, \ sizeof(array[0]), array }; \ __module_param_call(MODULE_PARAM_PREFIX, name, \ - param_array_set, param_array_get, \ + ¶m_array_ops, \ .arr = &__param_arr_##name, \ __same_type(array[0], bool), perm); \ __MODULE_PARM_TYPE(name, "array of " #type) @@ -223,11 +250,11 @@ extern int param_get_invbool(char *buffer, struct kernel_param *kp); #define module_param_array(name, type, nump, perm) \ module_param_array_named(name, name, type, nump, perm) -extern int param_array_set(const char *val, struct kernel_param *kp); -extern int param_array_get(char *buffer, struct kernel_param *kp); +extern struct kernel_param_ops param_array_ops; -extern int param_set_copystring(const char *val, struct kernel_param *kp); -extern int param_get_string(char *buffer, struct kernel_param *kp); +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 */ @@ -235,13 +262,13 @@ struct module; #if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES) extern int module_param_sysfs_setup(struct module *mod, - struct kernel_param *kparam, + const struct kernel_param *kparam, unsigned int num_params); extern void module_param_sysfs_remove(struct module *mod); #else static inline int module_param_sysfs_setup(struct module *mod, - struct kernel_param *kparam, + const struct kernel_param *kparam, unsigned int num_params) { return 0; -- cgit v1.1 From e6df34a4429b77fdffb6e05adf263468a3dcda33 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Aug 2010 23:04:17 -0600 Subject: param: add a free hook to kernel_param_ops. This allows us to generalize the KPARAM_KMALLOCED flag, by calling a function on every parameter when a module is unloaded. Signed-off-by: Rusty Russell Reviewed-by: Takashi Iwai Tested-by: Phil Carmody --- include/linux/moduleparam.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 02e5090..9f51568 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -36,6 +36,8 @@ struct kernel_param_ops { int (*set)(const char *val, const struct kernel_param *kp); /* Returns length written or -errno. Buffer is 4k (ie. be short!) */ int (*get)(char *buffer, const struct kernel_param *kp); + /* Optional function to free kp->arg when module unloaded. */ + void (*free)(void *arg); }; /* Flag bits for kernel_param.flags */ -- cgit v1.1 From 914dcaa84c53f2c3efa6016efcae13fd92a8a17c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Aug 2010 23:04:18 -0600 Subject: param: make param sections const. Since this section can be read-only (they're in .rodata), they should always have been const. Minor flow-through various functions. Signed-off-by: Rusty Russell Tested-by: Phil Carmody --- include/linux/moduleparam.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 9f51568..6d48831 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -161,7 +161,7 @@ __check_old_set_param(int (*oldset)(const char *, struct kernel_param *)) /* Called on module insert or kernel boot */ extern int parse_args(const char *name, char *args, - struct kernel_param *params, + const struct kernel_param *params, unsigned num, int (*unknown)(char *param, char *val)); -- cgit v1.1 From 907b29eb41aa604477a655bff7345731da94514d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Aug 2010 23:04:19 -0600 Subject: param: locking for kernel parameters There may be cases (most obviously, sysfs-writable charp parameters) where a module needs to prevent sysfs access to parameters. Rather than express this in terms of a big lock, the functions are expressed in terms of what they protect against. This is clearer, esp. if the implementation changes to a module-level or even param-level lock. Signed-off-by: Rusty Russell Reviewed-by: Takashi Iwai Tested-by: Phil Carmody --- include/linux/moduleparam.h | 56 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'include') diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 6d48831..ca74a34 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -130,6 +130,62 @@ __check_old_set_param(int (*oldset)(const char *, struct kernel_param *)) #define module_param(name, type, perm) \ module_param_named(name, name, type, perm) +/** + * kparam_block_sysfs_write - make sure a parameter isn't written via sysfs. + * @name: the name of the parameter + * + * There's no point blocking write on a paramter that isn't writable via sysfs! + */ +#define kparam_block_sysfs_write(name) \ + do { \ + BUG_ON(!(__param_##name.perm & 0222)); \ + __kernel_param_lock(); \ + } while (0) + +/** + * kparam_unblock_sysfs_write - allows sysfs to write to a parameter again. + * @name: the name of the parameter + */ +#define kparam_unblock_sysfs_write(name) \ + do { \ + BUG_ON(!(__param_##name.perm & 0222)); \ + __kernel_param_unlock(); \ + } while (0) + +/** + * kparam_block_sysfs_read - make sure a parameter isn't read via sysfs. + * @name: the name of the parameter + * + * This also blocks sysfs writes. + */ +#define kparam_block_sysfs_read(name) \ + do { \ + BUG_ON(!(__param_##name.perm & 0444)); \ + __kernel_param_lock(); \ + } while (0) + +/** + * kparam_unblock_sysfs_read - allows sysfs to read a parameter again. + * @name: the name of the parameter + */ +#define kparam_unblock_sysfs_read(name) \ + do { \ + BUG_ON(!(__param_##name.perm & 0444)); \ + __kernel_param_unlock(); \ + } while (0) + +#ifdef CONFIG_SYSFS +extern void __kernel_param_lock(void); +extern void __kernel_param_unlock(void); +#else +static inline void __kernel_param_lock(void) +{ +} +static inline void __kernel_param_unlock(void) +{ +} +#endif + #ifndef MODULE /** * core_param - define a historical core kernel parameter. -- cgit v1.1 From 546970bc6afc7fb37447fbac09b82c7884662c21 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Aug 2010 23:04:20 -0600 Subject: param: add kerneldoc to moduleparam.h Also reorders the macros with the most common ones at the top. Signed-off-by: Rusty Russell Reviewed-by: Takashi Iwai Tested-by: Phil Carmody --- include/linux/moduleparam.h | 121 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 95 insertions(+), 26 deletions(-) (limited to 'include') diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index ca74a34..893549c 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -71,6 +71,62 @@ struct kparam_array void *elem; }; +/** + * module_param - typesafe helper for a module/cmdline parameter + * @value: the variable to alter, and exposed parameter name. + * @type: the type of the parameter + * @perm: visibility in sysfs. + * + * @value becomes the module parameter, or (prefixed by KBUILD_MODNAME and a + * ".") the kernel commandline parameter. Note that - is changed to _, so + * the user can use "foo-bar=1" even for variable "foo_bar". + * + * @perm is 0 if the the variable is not to appear in sysfs, or 0444 + * for world-readable, 0644 for root-writable, etc. Note that if it + * is writable, you may need to use kparam_block_sysfs_write() around + * accesses (esp. charp, which can be kfreed when it changes). + * + * The @type is simply pasted to refer to a param_ops_##type and a + * param_check_##type: for convenience many standard types are provided but + * you can create your own by defining those variables. + * + * Standard types are: + * byte, short, ushort, int, uint, long, ulong + * charp: a character pointer + * bool: a bool, values 0/1, y/n, Y/N. + * invbool: the above, only sense-reversed (N = true). + */ +#define module_param(name, type, perm) \ + module_param_named(name, name, type, perm) + +/** + * module_param_named - typesafe helper for a renamed module/cmdline parameter + * @name: a valid C identifier which is the parameter name. + * @value: the actual lvalue to alter. + * @type: the type of the parameter + * @perm: visibility in sysfs. + * + * Usually it's a good idea to have variable names and user-exposed names the + * same, but that's harder if the variable must be non-static or is inside a + * structure. This allows exposure under a different name. + */ +#define module_param_named(name, value, type, perm) \ + param_check_##type(name, &(value)); \ + module_param_cb(name, ¶m_ops_##type, &value, perm); \ + __MODULE_PARM_TYPE(name, #type) + +/** + * module_param_cb - general callback for a module/cmdline parameter + * @name: a valid C identifier which is the parameter name. + * @ops: the set & get operations for this parameter. + * @perm: visibility in sysfs. + * + * The ops can have NULL set or get functions. + */ +#define module_param_cb(name, ops, arg, perm) \ + __module_param_call(MODULE_PARAM_PREFIX, \ + name, ops, arg, __same_type(*(arg), bool), perm) + /* On alpha, ia64 and ppc64 relocations to global data cannot go into read-only sections (which is part of respective UNIX ABI on these platforms). So 'const' makes no sense and even causes compile failures @@ -82,9 +138,7 @@ struct kparam_array #endif /* This is the fundamental function for registering boot/module - parameters. perm sets the visibility in sysfs: 000 means it's - not there, read bits mean it's readable, write bits mean it's - writable. */ + parameters. */ #define __module_param_call(prefix, name, ops, arg, isbool, perm) \ /* Default value instead of permissions? */ \ static int __param_perm_check_##name __attribute__((unused)) = \ @@ -113,23 +167,6 @@ __check_old_set_param(int (*oldset)(const char *, struct kernel_param *)) return 0; } -#define module_param_cb(name, ops, arg, perm) \ - __module_param_call(MODULE_PARAM_PREFIX, \ - name, ops, arg, __same_type(*(arg), bool), perm) - -/* - * Helper functions: type is byte, short, ushort, int, uint, long, - * ulong, charp, bool or invbool, or XXX if you define param_ops_XXX - * and param_check_XXX. - */ -#define module_param_named(name, value, type, perm) \ - param_check_##type(name, &(value)); \ - module_param_cb(name, ¶m_ops_##type, &value, perm); \ - __MODULE_PARM_TYPE(name, #type) - -#define module_param(name, type, perm) \ - module_param_named(name, name, type, perm) - /** * kparam_block_sysfs_write - make sure a parameter isn't written via sysfs. * @name: the name of the parameter @@ -191,7 +228,7 @@ static inline void __kernel_param_unlock(void) * core_param - define a historical core kernel parameter. * @name: the name of the cmdline and sysfs parameter (often the same as var) * @var: the variable - * @type: the type (for param_set_##type and param_get_##type) + * @type: the type of the parameter * @perm: visibility in sysfs * * core_param is just like module_param(), but cannot be modular and @@ -205,7 +242,16 @@ static inline void __kernel_param_unlock(void) &var, __same_type(var, bool), perm) #endif /* !MODULE */ -/* Actually copy string: maxlen param is usually sizeof(string). */ +/** + * module_param_string - a char array parameter + * @name: the name of the parameter + * @string: the string variable + * @len: the maximum length of the string, incl. terminator + * @perm: visibility in sysfs. + * + * This actually copies the string when it's set (unlike type charp). + * @len is usually just sizeof(string). + */ #define module_param_string(name, string, len, perm) \ static const struct kparam_string __param_string_##name \ = { len, string }; \ @@ -294,7 +340,33 @@ extern int param_set_invbool(const char *val, const struct kernel_param *kp); extern int param_get_invbool(char *buffer, const struct kernel_param *kp); #define param_check_invbool(name, p) __param_check(name, p, bool) -/* Comma-separated array: *nump is set to number they actually specified. */ +/** + * module_param_array - a parameter which is an array of some type + * @name: the name of the array variable + * @type: the type, as per module_param() + * @nump: optional pointer filled in with the number written + * @perm: visibility in sysfs + * + * Input and output are as comma-separated values. Commas inside values + * don't work properly (eg. an array of charp). + * + * ARRAY_SIZE(@name) is used to determine the number of elements in the + * array, so the definition must be visible. + */ +#define module_param_array(name, type, nump, perm) \ + module_param_array_named(name, name, type, nump, perm) + +/** + * module_param_array_named - renamed parameter which is an array of some type + * @name: a valid C identifier which is the parameter name + * @array: the name of the array variable + * @type: the type, as per module_param() + * @nump: optional pointer filled in with the number written + * @perm: visibility in sysfs + * + * This exposes a different name than the actual variable name. See + * module_param_named() for why this might be necessary. + */ #define module_param_array_named(name, array, type, nump, perm) \ static const struct kparam_array __param_arr_##name \ = { ARRAY_SIZE(array), nump, ¶m_ops_##type, \ @@ -305,9 +377,6 @@ extern int param_get_invbool(char *buffer, const struct kernel_param *kp); __same_type(array[0], bool), perm); \ __MODULE_PARM_TYPE(name, "array of " #type) -#define module_param_array(name, type, nump, perm) \ - module_param_array_named(name, name, type, nump, perm) - extern struct kernel_param_ops param_array_ops; extern struct kernel_param_ops param_ops_string; -- cgit v1.1 From a6de51b2787012ba3ab62c7d50df1b749b83d5f0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Aug 2010 23:04:40 -0600 Subject: param: don't deref arg in __same_type() checks gcc allows this when arg is a function, but sparse complains: drivers/char/ipmi/ipmi_watchdog.c:303:1: error: cannot dereference this type drivers/char/ipmi/ipmi_watchdog.c:307:1: error: cannot dereference this type drivers/char/ipmi/ipmi_watchdog.c:311:1: error: cannot dereference this type Reported-by: Randy Dunlap Tested-by: Randy Dunlap Signed-off-by: Rusty Russell --- include/linux/moduleparam.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 893549c..9d2f183 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -125,7 +125,7 @@ struct kparam_array */ #define module_param_cb(name, ops, arg, perm) \ __module_param_call(MODULE_PARAM_PREFIX, \ - name, ops, arg, __same_type(*(arg), bool), perm) + name, ops, arg, __same_type((arg), bool *), perm) /* On alpha, ia64 and ppc64 relocations to global data cannot go into read-only sections (which is part of respective UNIX ABI on these @@ -157,7 +157,7 @@ struct kparam_array { (void *)set, (void *)get }; \ __module_param_call(MODULE_PARAM_PREFIX, \ name, &__param_ops_##name, arg, \ - __same_type(*(arg), bool), \ + __same_type(arg, bool *), \ (perm) + sizeof(__check_old_set_param(set))*0) /* We don't get oldget: it's often a new-style param_get_uint, etc. */ @@ -330,9 +330,9 @@ extern int param_get_bool(char *buffer, const struct kernel_param *kp); #define param_check_bool(name, p) \ static inline void __check_##name(void) \ { \ - BUILD_BUG_ON(!__same_type(*(p), bool) && \ - !__same_type(*(p), unsigned int) && \ - !__same_type(*(p), int)); \ + BUILD_BUG_ON(!__same_type((p), bool *) && \ + !__same_type((p), unsigned int *) && \ + !__same_type((p), int *)); \ } extern struct kernel_param_ops param_ops_invbool; -- cgit v1.1 From 13bcbc008790b05413c9a16763b423c206528c0a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 10 Aug 2010 18:01:09 -0700 Subject: include/linux/fs.h: complete hexification of FMODE_* constants One straggler which was missed due to merge ordering issues. Cc: Wu Fengguang Cc: Eric Paris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/fs.h b/include/linux/fs.h index 1542e0e..267d026 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -93,7 +93,7 @@ struct inodes_stat_t { #define FMODE_RANDOM ((__force fmode_t)0x1000) /* File was opened by fanotify and shouldn't generate fanotify events */ -#define FMODE_NONOTIFY ((__force fmode_t)16777216) /* 0x1000000 */ +#define FMODE_NONOTIFY ((__force fmode_t)0x1000000) /* * The below are the various read and write types that we support. Some of -- cgit v1.1 From 083c8c1e60e5c27a277e87dbeb6b89b47937559f Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Tue, 10 Aug 2010 18:01:24 -0700 Subject: scsi: use __uX types for headers exported to user space Commit 9e4f5e29 ("FC Pass Thru support") exported a number of header files in include/scsi to user space, but didn't change the uX types to the userspace-compatible __uX types. Without that you'll get compile errors when including them - E.G.: include/scsi/scsi.h:145: error: expected specifier-qualifier-list before `u8' Signed-off-by: Peter Korsgaard Cc: Boaz Harrosh Cc: James Smart Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/scsi/scsi.h | 8 ++++---- include/scsi/scsi_netlink.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 9ae5c61..8fcb6e0 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -151,10 +151,10 @@ struct scsi_cmnd; /* defined in T10 SCSI Primary Commands-2 (SPC2) */ struct scsi_varlen_cdb_hdr { - u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */ - u8 control; - u8 misc[5]; - u8 additional_cdb_length; /* total cdb length - 8 */ + __u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */ + __u8 control; + __u8 misc[5]; + __u8 additional_cdb_length; /* total cdb length - 8 */ __be16 service_action; /* service specific data follows */ }; diff --git a/include/scsi/scsi_netlink.h b/include/scsi/scsi_netlink.h index 536752c..58ce8fe 100644 --- a/include/scsi/scsi_netlink.h +++ b/include/scsi/scsi_netlink.h @@ -105,8 +105,8 @@ struct scsi_nl_host_vendor_msg { * PCI : ID data is the 16 bit PCI Registered Vendor ID */ #define SCSI_NL_VID_TYPE_SHIFT 56 -#define SCSI_NL_VID_TYPE_MASK ((u64)0xFF << SCSI_NL_VID_TYPE_SHIFT) -#define SCSI_NL_VID_TYPE_PCI ((u64)0x01 << SCSI_NL_VID_TYPE_SHIFT) +#define SCSI_NL_VID_TYPE_MASK ((__u64)0xFF << SCSI_NL_VID_TYPE_SHIFT) +#define SCSI_NL_VID_TYPE_PCI ((__u64)0x01 << SCSI_NL_VID_TYPE_SHIFT) #define SCSI_NL_VID_ID_MASK (~ SCSI_NL_VID_TYPE_MASK) -- cgit v1.1 From 5a19ae4bb003a428b9c8367daf05eed5029dc4cd Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 10 Aug 2010 18:01:28 -0700 Subject: virtio_9p.h: include linux/types.h Add to so that types are explicitly defined: linux/virtio_9p.h:15: found __[us]{8,16,32,64} type without #include Signed-off-by: Randy Dunlap Cc: Eric Van Hensbergen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/virtio_9p.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h index 395c38a..1faa80d 100644 --- a/include/linux/virtio_9p.h +++ b/include/linux/virtio_9p.h @@ -2,6 +2,7 @@ #define _LINUX_VIRTIO_9P_H /* This header is BSD licensed so anyone can use the definitions to implement * compatible drivers/servers. */ +#include #include #include #include -- cgit v1.1 From 454eedb8901da895fb602998fa588cd62875d07d Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 10 Aug 2010 18:01:29 -0700 Subject: vfs: O_* bit numbers uniqueness check The O_* bit numbers are defined in 20+ arch/*, and can silently overlap. Add a compile time check to ensure the uniqueness as suggested by David Miller. Signed-off-by: Wu Fengguang Cc: David Miller Cc: Stephen Rothwell Cc: Al Viro Cc: Christoph Hellwig Cc: Eric Paris Cc: Roland Dreier Cc: Jamie Lokier Cc: Andreas Schwab Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/fcntl.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h index e3cbc38..a70b2d2 100644 --- a/include/asm-generic/fcntl.h +++ b/include/asm-generic/fcntl.h @@ -11,6 +11,10 @@ * -Eric Paris */ +/* + * When introducing new O_* bits, please check its uniqueness in fcntl_init(). + */ + #define O_ACCMODE 00000003 #define O_RDONLY 00000000 #define O_WRONLY 00000001 -- cgit v1.1 From 6da24b786ed1963a7f872c1899627968c76d17d7 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Tue, 10 Aug 2010 18:01:36 -0700 Subject: mmc: recognize CSD structure The eMMC spec 4.4 and 4.3 + additional feature chips has CSD structure version 3 and version 3 have to check the CSD_STRUCTURE byte in the EXT_CSD register. Also fix EXT_CSD revision message. [akpm@linux-foundation.org: fix comment, per Chris Ball] Signed-off-by: Kyungmin Park Cc: Adrian Hunter Cc: Chris Ball Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmc/card.h | 1 + include/linux/mmc/mmc.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index d02d2c6..c83c7a7 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -24,6 +24,7 @@ struct mmc_cid { }; struct mmc_csd { + unsigned char structure; unsigned char mmca_vsn; unsigned short cmdclass; unsigned short tacc_clks; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 8a49cbf..52ce988 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -254,6 +254,7 @@ struct _mmc_csd { #define EXT_CSD_BUS_WIDTH 183 /* R/W */ #define EXT_CSD_HS_TIMING 185 /* R/W */ #define EXT_CSD_CARD_TYPE 196 /* RO */ +#define EXT_CSD_STRUCTURE 194 /* RO */ #define EXT_CSD_REV 192 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_S_A_TIMEOUT 217 -- cgit v1.1 From 7310ece86ad7da027f85a37a0638164118a5d12f Mon Sep 17 00:00:00 2001 From: Michal Miroslaw Date: Tue, 10 Aug 2010 18:01:40 -0700 Subject: mmc: implement SD-combo (IO+mem) support Signed-off-by: Michal Miroslaw Cc: Adrian Hunter Cc: Chris Ball Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmc/card.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index c83c7a7..340d391 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -93,6 +93,7 @@ struct mmc_card { #define MMC_TYPE_MMC 0 /* MMC card */ #define MMC_TYPE_SD 1 /* SD card */ #define MMC_TYPE_SDIO 2 /* SDIO card */ +#define MMC_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */ unsigned int state; /* (our) card state */ #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */ #define MMC_STATE_READONLY (1<<1) /* card is read-only */ -- cgit v1.1 From 4c2ef25fe0b847d2ae818f74758ddb0be1c27d8e Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Tue, 10 Aug 2010 18:01:41 -0700 Subject: mmc: fix all hangs related to mmc/sd card insert/removal during suspend/resume If you don't use CONFIG_MMC_UNSAFE_RESUME, as soon as you attempt to suspend, the card will be removed, therefore this patch doesn't change the behavior of this option. However the removal will be done by pm notifier, which runs while userspace is still not frozen and thus can freely use del_gendisk, without the risk of deadlock which would happen otherwise. Card detect workqueue is now disabled while userspace is frozen, Therefore if you do use CONFIG_MMC_UNSAFE_RESUME, and remove the card during suspend, the removal will be detected as soon as userspace is unfrozen, again at the moment it is safe to call del_gendisk. Tested with and without CONFIG_MMC_UNSAFE_RESUME with suspend and hibernate. [akpm@linux-foundation.org: clean up function prototype] [akpm@linux-foundation.org: fix CONFIG_PM-n linkage, small cleanups] [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Maxim Levitsky Cc: David Brownell Cc: Alan Stern Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmc/host.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index f65913c..513ff03 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -124,6 +124,7 @@ struct mmc_host { unsigned int f_min; unsigned int f_max; u32 ocr_avail; + struct notifier_block pm_notify; #define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ #define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ @@ -183,6 +184,7 @@ struct mmc_host { /* Only used with MMC_CAP_DISABLE */ int enabled; /* host is enabled */ + int rescan_disable; /* disable card detection */ int nesting_cnt; /* "enable" nesting count */ int en_dis_recurs; /* detect recursion */ unsigned int disable_delay; /* disable delay in msecs */ @@ -257,6 +259,7 @@ int mmc_card_can_sleep(struct mmc_host *host); int mmc_host_enable(struct mmc_host *host); int mmc_host_disable(struct mmc_host *host); int mmc_host_lazy_disable(struct mmc_host *host); +int mmc_pm_notify(struct notifier_block *notify_block, unsigned long, void *); static inline void mmc_set_disable_delay(struct mmc_host *host, unsigned int disable_delay) -- cgit v1.1 From 6f51be3d37dff73cf8db771df4169f4c2f1cbf66 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Tue, 10 Aug 2010 18:01:50 -0700 Subject: sdio: allow non-standard SDIO cards There are some chips (like TI WL12xx series) that can be interfaced over SDIO but don't support the SDIO specification, meaning that they are missing CIA (Common I/O Area) with all it's registers. Current Linux SDIO implementation relies on those registers to identify and configure the card, so non-standard cards can not function and cause lots of warnings from the core when it reads invalid data from non-existent registers. After this patch, init_card() host callback can now set new quirk MMC_QUIRK_NONSTD_SDIO, which means that SDIO core should not try to access any standard SDIO registers and rely on init_card() to fill all SDIO structures instead. As those cards are usually embedded chips, all the required information can be obtained from machine board files by the host driver when it's called through init_card() callback. Signed-off-by: Grazvydas Ignotas Cc: Adrian Hunter Cc: Tony Lindgren Cc: Bob Copeland Cc: Kalle Valo Cc: Madhusudhan Chikkature Cc: Kishore Kadiyala Cc: Russell King Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmc/card.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 340d391..4d893ea 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -103,6 +103,8 @@ struct mmc_card { #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ /* for byte mode */ +#define MMC_QUIRK_NONSTD_SDIO (1<<2) /* non-standard SDIO card attached */ + /* (missing CIA registers) */ u32 raw_cid[4]; /* raw card CID */ u32 raw_csd[4]; /* raw card CSD */ -- cgit v1.1 From 4a22b8a4ad5561436b16f5278d2f9e406ffb8705 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 10 Aug 2010 18:02:23 -0700 Subject: gpio: max730x: make pullups configurable via platformdata The gpios on the max730x chips have support for internal pullups while in input mode. This patch adds support for configuring these pullups via platform data. A new member ("input_pullup_active") to the platform data struct is introduced. A set bit in this variable activates the pullups while the respective port is in input mode. This is a compatible enhancement since unset bits lead to disables pullups which was the default in the original driver. _Note_: the 4 lowest bits in "input_pullup_active" are unused because the first 4 ports of the controller are not used, too. Signed-off-by: Marc Kleine-Budde Reviewed-by: Wolfram Sang Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/spi/max7301.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/linux/spi/max7301.h b/include/linux/spi/max7301.h index 34af0a3..bcaa2f7 100644 --- a/include/linux/spi/max7301.h +++ b/include/linux/spi/max7301.h @@ -11,6 +11,7 @@ struct max7301 { struct mutex lock; u8 port_config[8]; /* field 0 is unused */ u32 out_level; /* cached output levels */ + u32 input_pullup_active; struct gpio_chip chip; struct device *dev; int (*write)(struct device *dev, unsigned int reg, unsigned int val); @@ -20,6 +21,13 @@ struct max7301 { struct max7301_platform_data { /* number assigned to the first GPIO */ unsigned base; + /* + * bitmask controlling the pullup configuration, + * + * _note_ the 4 lowest bits are unused, because the first 4 + * ports of the controller are not used, too. + */ + u32 input_pullup_active; }; extern int __max730x_remove(struct device *dev); -- cgit v1.1 From c34f16b70a52e348a62944fe0d5c7c1eb9ad5b72 Mon Sep 17 00:00:00 2001 From: Gregory Bean Date: Tue, 10 Aug 2010 18:02:27 -0700 Subject: gpio: sx150x: add Semtech I2C sx150x gpio expander driver Add support for Semtech SX150-series I2C GPIO expanders. Compatible models include: 8 bits: sx1508q 16 bits: sx1509q Signed-off-by: Gregory Bean Cc: David Brownell Cc: Jean Delvare Cc: Trilok Soni Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/i2c/sx150x.h | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 include/linux/i2c/sx150x.h (limited to 'include') diff --git a/include/linux/i2c/sx150x.h b/include/linux/i2c/sx150x.h new file mode 100644 index 0000000..ee3049c --- /dev/null +++ b/include/linux/i2c/sx150x.h @@ -0,0 +1,78 @@ +/* + * Driver for the Semtech SX150x I2C GPIO Expanders + * + * Copyright (c) 2010, Code Aurora Forum. 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 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. + */ +#ifndef __LINUX_I2C_SX150X_H +#define __LINUX_I2C_SX150X_H + +/** + * struct sx150x_platform_data - config data for SX150x driver + * @gpio_base: The index number of the first GPIO assigned to this + * GPIO expander. The expander will create a block of + * consecutively numbered gpios beginning at the given base, + * with the size of the block depending on the model of the + * expander chip. + * @oscio_is_gpo: If set to true, the driver will configure OSCIO as a GPO + * instead of as an oscillator, increasing the size of the + * GP(I)O pool created by this expander by one. The + * output-only GPO pin will be added at the end of the block. + * @io_pullup_ena: A bit-mask which enables or disables the pull-up resistor + * for each IO line in the expander. Setting the bit at + * position n will enable the pull-up for the IO at + * the corresponding offset. For chips with fewer than + * 16 IO pins, high-end bits are ignored. + * @io_pulldn_ena: A bit-mask which enables-or disables the pull-down + * resistor for each IO line in the expander. Setting the + * bit at position n will enable the pull-down for the IO at + * the corresponding offset. For chips with fewer than + * 16 IO pins, high-end bits are ignored. + * @io_open_drain_ena: A bit-mask which enables-or disables open-drain + * operation for each IO line in the expander. Setting the + * bit at position n enables open-drain operation for + * the IO at the corresponding offset. Clearing the bit + * enables regular push-pull operation for that IO. + * For chips with fewer than 16 IO pins, high-end bits + * are ignored. + * @io_polarity: A bit-mask which enables polarity inversion for each IO line + * in the expander. Setting the bit at position n inverts + * the polarity of that IO line, while clearing it results + * in normal polarity. For chips with fewer than 16 IO pins, + * high-end bits are ignored. + * @irq_summary: The 'summary IRQ' line to which the GPIO expander's INT line + * is connected, via which it reports interrupt events + * across all GPIO lines. This must be a real, + * pre-existing IRQ line. + * Setting this value < 0 disables the irq_chip functionality + * of the driver. + * @irq_base: The first 'virtual IRQ' line at which our block of GPIO-based + * IRQ lines will appear. Similarly to gpio_base, the expander + * will create a block of irqs beginning at this number. + * This value is ignored if irq_summary is < 0. + */ +struct sx150x_platform_data { + unsigned gpio_base; + bool oscio_is_gpo; + u16 io_pullup_ena; + u16 io_pulldn_ena; + u16 io_open_drain_ena; + u16 io_polarity; + int irq_summary; + unsigned irq_base; +}; + +#endif /* __LINUX_I2C_SX150X_H */ -- cgit v1.1 From 158e0a2d1b3cffed8b46cbc56393a1394672ef79 Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Tue, 10 Aug 2010 18:03:00 -0700 Subject: memcg: use find_lock_task_mm() in memory cgroups oom When the OOM killer scans task, it check a task is under memcg or not when it's called via memcg's context. But, as Oleg pointed out, a thread group leader may have NULL ->mm and task_in_mem_cgroup() may do wrong decision. We have to use find_lock_task_mm() in memcg as generic OOM-Killer does. Signed-off-by: KAMEZAWA Hiroyuki Cc: Oleg Nesterov Cc: Daisuke Nishimura Cc: Balbir Singh Reviewed-by: Minchan Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/oom.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/oom.h b/include/linux/oom.h index f209b68..5e3aa83 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -66,6 +66,8 @@ static inline void oom_killer_enable(void) extern unsigned long badness(struct task_struct *p, struct mem_cgroup *mem, const nodemask_t *nodemask, unsigned long uptime); +extern struct task_struct *find_lock_task_mm(struct task_struct *p); + /* sysctls */ extern int sysctl_oom_dump_tasks; extern int sysctl_oom_kill_allocating_task; -- cgit v1.1 From 14fec79680f7cc4617d6ba69324e63d4a732986c Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 10 Aug 2010 18:03:05 -0700 Subject: memcg: mem_cgroup_shrink_node_zone() doesn't need sc.nodemask Currently mem_cgroup_shrink_node_zone() call shrink_zone() directly. thus it doesn't need to initialize sc.nodemask because shrink_zone() doesn't use it at all. Signed-off-by: KOSAKI Motohiro Acked-by: KAMEZAWA Hiroyuki Acked-by: Mel Gorman Cc: Balbir Singh Cc: Nishimura Daisuke Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/swap.h b/include/linux/swap.h index 91c9d3f..2fee51a 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -244,8 +244,7 @@ extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem, extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, gfp_t gfp_mask, bool noswap, unsigned int swappiness, - struct zone *zone, - int nid); + struct zone *zone); extern int __isolate_lru_page(struct page *page, int mode, int file); extern unsigned long shrink_all_memory(unsigned long nr_pages); extern int vm_swappiness; -- cgit v1.1 From 00918b6ab89df8984ca06397cb77994dabd73f9b Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 10 Aug 2010 18:03:05 -0700 Subject: memcg: remove nid and zid argument from mem_cgroup_soft_limit_reclaim() mem_cgroup_soft_limit_reclaim() has zone, nid and zid argument. but nid and zid can be calculated from zone. So remove it. Signed-off-by: KOSAKI Motohiro Acked-by: KAMEZAWA Hiroyuki Acked-by: Mel Gorman Cc: Balbir Singh Cc: Nishimura Daisuke Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 73564ca..159a076 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -123,8 +123,7 @@ static inline bool mem_cgroup_disabled(void) void mem_cgroup_update_file_mapped(struct page *page, int val); unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, - gfp_t gfp_mask, int nid, - int zid); + gfp_t gfp_mask); u64 mem_cgroup_get_limit(struct mem_cgroup *mem); #else /* CONFIG_CGROUP_MEM_RES_CTLR */ @@ -301,7 +300,7 @@ static inline void mem_cgroup_update_file_mapped(struct page *page, static inline unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, - gfp_t gfp_mask, int nid, int zid) + gfp_t gfp_mask) { return 0; } -- cgit v1.1 From a6eb9fe105d5de0053b261148cee56c94b4720ca Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 10 Aug 2010 18:03:22 -0700 Subject: dma-mapping: rename ARCH_KMALLOC_MINALIGN to ARCH_DMA_MINALIGN Now each architecture has the own dma_get_cache_alignment implementation. dma_get_cache_alignment returns the minimum DMA alignment. Architectures define it as ARCH_KMALLOC_MINALIGN (it's used to make sure that malloc'ed buffer is DMA-safe; the buffer doesn't share a cache with the others). So we can unify dma_get_cache_alignment implementations. This patch: dma_get_cache_alignment() needs to know if an architecture defines ARCH_KMALLOC_MINALIGN or not (needs to know if architecture has DMA alignment restriction). However, slab.h define ARCH_KMALLOC_MINALIGN if architectures doesn't define it. Let's rename ARCH_KMALLOC_MINALIGN to ARCH_DMA_MINALIGN. ARCH_KMALLOC_MINALIGN is used only in the internals of slab/slob/slub (except for crypto). Signed-off-by: FUJITA Tomonori Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/slab_def.h | 4 +++- include/linux/slob_def.h | 4 +++- include/linux/slub_def.h | 8 +++++--- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index 1acfa73..791a502 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h @@ -17,7 +17,6 @@ #include -#ifndef ARCH_KMALLOC_MINALIGN /* * Enforce a minimum alignment for the kmalloc caches. * Usually, the kmalloc caches are cache_line_size() aligned, except when @@ -27,6 +26,9 @@ * ARCH_KMALLOC_MINALIGN allows that. * Note that increasing this value may disable some debug features. */ +#ifdef ARCH_DMA_MINALIGN +#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN +#else #define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long) #endif diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h index 62667f7..4382db0 100644 --- a/include/linux/slob_def.h +++ b/include/linux/slob_def.h @@ -1,7 +1,9 @@ #ifndef __LINUX_SLOB_DEF_H #define __LINUX_SLOB_DEF_H -#ifndef ARCH_KMALLOC_MINALIGN +#ifdef ARCH_DMA_MINALIGN +#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN +#else #define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long) #endif diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 6447a72..6d14409 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -106,15 +106,17 @@ struct kmem_cache { /* * Kmalloc subsystem. */ -#if defined(ARCH_KMALLOC_MINALIGN) && ARCH_KMALLOC_MINALIGN > 8 -#define KMALLOC_MIN_SIZE ARCH_KMALLOC_MINALIGN +#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) -#ifndef ARCH_KMALLOC_MINALIGN +#ifdef ARCH_DMA_MINALIGN +#define ARCH_KMALLOC_MINALIGN ARCH_DMA_MINALIGN +#else #define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long) #endif -- cgit v1.1 From 4565f0170dfc849b3629c27d769db800467baa62 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 10 Aug 2010 18:03:22 -0700 Subject: dma-mapping: unify dma_get_cache_alignment implementations dma_get_cache_alignment returns the minimum DMA alignment. Architectures defines it as ARCH_DMA_MINALIGN (formally ARCH_KMALLOC_MINALIGN). So we can unify dma_get_cache_alignment implementations. Note that some architectures implement dma_get_cache_alignment wrongly. dma_get_cache_alignment() should return the minimum DMA alignment. So fully-coherent architectures should return 1. This patch also fixes this issue. Signed-off-by: FUJITA Tomonori Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/dma-mapping.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 89b7e1a..e0670a5 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -142,6 +142,14 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask) return -EIO; } +static inline int dma_get_cache_alignment(void) +{ +#ifdef ARCH_DMA_MINALIGN + return ARCH_DMA_MINALIGN; +#endif + return 1; +} + /* flags for the coherent memory api */ #define DMA_MEMORY_MAP 0x01 #define DMA_MEMORY_IO 0x02 -- cgit v1.1 From 3b9c6c11f519718d618f5d7c9508daf78b207f6f Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 10 Aug 2010 18:03:25 -0700 Subject: dma-mapping: remove dma_is_consistent API Architectures implement dma_is_consistent() in different ways (some misinterpret the definition of API in DMA-API.txt). So it hasn't been so useful for drivers. We have only one user of the API in tree. Unlikely out-of-tree drivers use the API. Even if we fix dma_is_consistent() in some architectures, it doesn't look useful at all. It was invented long ago for some old systems that can't allocate coherent memory at all. It's better to export only APIs that are definitely necessary for drivers. Let's remove this API. Signed-off-by: FUJITA Tomonori Cc: James Bottomley Reviewed-by: Konrad Rzeszutek Wilk Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/dma-mapping-broken.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h index 82cd0cb..ccf7b4f 100644 --- a/include/asm-generic/dma-mapping-broken.h +++ b/include/asm-generic/dma-mapping-broken.h @@ -72,9 +72,6 @@ dma_set_mask(struct device *dev, u64 mask); extern int dma_get_cache_alignment(void); -extern int -dma_is_consistent(struct device *dev, dma_addr_t dma_handle); - extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction); -- cgit v1.1 From c7ff0d9c92435e836e13aaa8d0e56d4000424bcc Mon Sep 17 00:00:00 2001 From: TAMUKI Shoichi Date: Tue, 10 Aug 2010 18:03:28 -0700 Subject: panic: keep blinking in spite of long spin timer mode To keep panic_timeout accuracy when running under a hypervisor, the current implementation only spins on long time (1 second) calls to mdelay. That brings a good effect, but the problem is the keyboard LEDs don't blink at all on that situation. This patch changes to call to panic_blink_enter() between every mdelay and keeps blinking in spite of long spin timer mode. The time to call to mdelay is now 100ms. Even this change will keep panic_timeout accuracy enough when running under a hypervisor. Signed-off-by: TAMUKI Shoichi Cc: Ben Dooks Cc: Russell King Acked-by: Dmitry Torokhov Cc: Anton Blanchard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 5b57236..452833d 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -177,7 +177,7 @@ struct va_format { }; extern struct atomic_notifier_head panic_notifier_list; -extern long (*panic_blink)(long time); +extern long (*panic_blink)(int state); NORET_TYPE void panic(const char * fmt, ...) __attribute__ ((NORET_AND format (printf, 1, 2))) __cold; extern void oops_enter(void); -- cgit v1.1 From 863a6049202412a6d655d052eb1c45ca7dd74a83 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 10 Aug 2010 18:03:30 -0700 Subject: lib/bug.c: add oops end marker to WARN implementation We are missing the oops end marker for the exception based WARN implementation in lib/bug.c. This is useful for logfile analysis tools. Signed-off-by: Anton Blanchard Cc: Ingo Molnar Cc: Arjan van de Ven Cc: "Kirill A. Shutemov" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kernel.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 452833d..d848cb8 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -182,6 +182,7 @@ NORET_TYPE void panic(const char * fmt, ...) __attribute__ ((NORET_AND format (printf, 1, 2))) __cold; extern void oops_enter(void); extern void oops_exit(void); +void print_oops_end_marker(void); extern int oops_may_print(void); NORET_TYPE void do_exit(long error_code) ATTRIB_NORET; -- cgit v1.1 From 0bcaa65a56ab74003666cf741b0bfa1e9263a11c Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 10 Aug 2010 18:03:33 -0700 Subject: fs/sysv: v7: adjust sanity checks for some volumes Newly mkfs-ed filesystems from Seventh Edition have last modification time set to zero, but are otherwise perfectly valid. Also, tighten up other sanity checks to filter out most filesystems with [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Lubomir Rintel Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sysv_fs.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/linux/sysv_fs.h b/include/linux/sysv_fs.h index 9641130..e47d6d9 100644 --- a/include/linux/sysv_fs.h +++ b/include/linux/sysv_fs.h @@ -148,6 +148,17 @@ struct v7_super_block { char s_fname[6]; /* file system name */ char s_fpack[6]; /* file system pack name */ }; +/* Constants to aid sanity checking */ +/* This is not a hard limit, nor enforced by v7 kernel. It's actually just + * the limit used by Seventh Edition's ls, though is high enough to assume + * that no reasonable file system would have that much entries in root + * directory. Thus, if we see anything higher, we just probably got the + * endiannes wrong. */ +#define V7_NFILES 1024 +/* The disk addresses are three-byte (despite direct block addresses being + * aligned word-wise in inode). If the most significant byte is non-zero, + * something is most likely wrong (not a filesystem, bad bytesex). */ +#define V7_MAXSIZE 0x00ffffff /* Coherent super-block data on disk */ #define COH_NICINOD 100 /* number of inode cache entries */ -- cgit v1.1 From ad9c7ed0685406fe3cd7f0749b82bf433a39dd9c Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 10 Aug 2010 18:03:34 -0700 Subject: kfifo: kfifo_is_{full,empty} should return bools, not ints For consistency with other kfifo routines, return bool, not int. Signed-off-by: Robert P. J. Day Cc: Stefani Seibold Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kfifo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 9fad052..57c4eed 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -171,7 +171,7 @@ static inline unsigned int kfifo_len(struct kfifo *fifo) * kfifo_is_empty - returns true if the fifo is empty * @fifo: the fifo to be used. */ -static inline __must_check int kfifo_is_empty(struct kfifo *fifo) +static inline __must_check bool kfifo_is_empty(struct kfifo *fifo) { return fifo->in == fifo->out; } @@ -180,7 +180,7 @@ static inline __must_check int kfifo_is_empty(struct kfifo *fifo) * kfifo_is_full - returns true if the fifo is full * @fifo: the fifo to be used. */ -static inline __must_check int kfifo_is_full(struct kfifo *fifo) +static inline __must_check bool kfifo_is_full(struct kfifo *fifo) { return kfifo_len(fifo) == kfifo_size(fifo); } -- cgit v1.1 From 4201d9a8e86b51dd40aa8a0dabd093376c859985 Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Tue, 10 Aug 2010 18:03:38 -0700 Subject: kfifo: add the new generic kfifo API Add the new version of the kfifo API files kfifo.c and kfifo.h. Signed-off-by: Stefani Seibold Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kfifo-new.h | 844 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 844 insertions(+) create mode 100644 include/linux/kfifo-new.h (limited to 'include') diff --git a/include/linux/kfifo-new.h b/include/linux/kfifo-new.h new file mode 100644 index 0000000..311f875 --- /dev/null +++ b/include/linux/kfifo-new.h @@ -0,0 +1,844 @@ +/* + * A generic kernel FIFO implementation + * + * Copyright (C) 2009/2010 Stefani Seibold + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _LINUX_KFIFO_H +#define _LINUX_KFIFO_H + +/* + * How to porting drivers to the new generic FIFO API: + * + * - Modify the declaration of the "struct kfifo *" object into a + * in-place "struct kfifo" object + * - Init the in-place object with kfifo_alloc() or kfifo_init() + * Note: The address of the in-place "struct kfifo" object must be + * passed as the first argument to this functions + * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get + * into kfifo_out + * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get + * into kfifo_out_spinlocked + * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc + * must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked + * as the last parameter + * - The formerly __kfifo_* functions are renamed into kfifo_* + */ + +/* + * Note about locking : There is no locking required until only * one reader + * and one writer is using the fifo and no kfifo_reset() will be * called + * kfifo_reset_out() can be safely used, until it will be only called + * in the reader thread. + * For multiple writer and one reader there is only a need to lock the writer. + * And vice versa for only one writer and multiple reader there is only a need + * to lock the reader. + */ + +#include +#include +#include +#include + +struct __kfifo { + unsigned int in; + unsigned int out; + unsigned int mask; + unsigned int esize; + void *data; +}; + +#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ + union { \ + struct __kfifo kfifo; \ + datatype *type; \ + char (*rectype)[recsize]; \ + ptrtype *ptr; \ + const ptrtype *ptr_const; \ + } + +#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ +{ \ + __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ + type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ +} + +#define STRUCT_KFIFO(type, size) \ + struct __STRUCT_KFIFO(type, size, 0, type) + +#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ +{ \ + __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ + type buf[0]; \ +} + +#define STRUCT_KFIFO_PTR(type) \ + struct __STRUCT_KFIFO_PTR(type, 0, type) + +/* + * define compatibility "struct kfifo" for dynamic allocated fifos + */ +struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); + +#define STRUCT_KFIFO_REC_1(size) \ + struct __STRUCT_KFIFO(unsigned char, size, 1, void) + +#define STRUCT_KFIFO_REC_2(size) \ + struct __STRUCT_KFIFO(unsigned char, size, 2, void) + +/* + * define kfifo_rec types + */ +struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); +struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); + +/* + * helper macro to distinguish between real in place fifo where the fifo + * array is a part of the structure and the fifo type where the array is + * outside of the fifo structure. + */ +#define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo)) + +/** + * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object + * @fifo: name of the declared fifo + * @type: type of the fifo elements + */ +#define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo + +/** + * DECLARE_KFIFO - macro to declare a fifo object + * @fifo: name of the declared fifo + * @type: type of the fifo elements + * @size: the number of elements in the fifo, this must be a power of 2 + */ +#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo + +/** + * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO + * @fifo: name of the declared fifo datatype + */ +#define INIT_KFIFO(fifo) \ +(void)({ \ + typeof(&(fifo)) __tmp = &(fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + __kfifo->in = 0; \ + __kfifo->out = 0; \ + __kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ + __kfifo->esize = sizeof(*__tmp->buf); \ + __kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \ +}) + +/** + * DEFINE_KFIFO - macro to define and initialize a fifo + * @fifo: name of the declared fifo datatype + * @type: type of the fifo elements + * @size: the number of elements in the fifo, this must be a power of 2 + * + * Note: the macro can be used for global and local fifo data type variables. + */ +#define DEFINE_KFIFO(fifo, type, size) \ + DECLARE_KFIFO(fifo, type, size) = \ + (typeof(fifo)) { \ + { \ + { \ + .in = 0, \ + .out = 0, \ + .mask = __is_kfifo_ptr(&(fifo)) ? \ + 0 : \ + ARRAY_SIZE((fifo).buf) - 1, \ + .esize = sizeof(*(fifo).buf), \ + .data = __is_kfifo_ptr(&(fifo)) ? \ + NULL : \ + (fifo).buf, \ + } \ + } \ + } + + +static inline unsigned int __must_check +__kfifo_must_check_helper(unsigned int val) +{ + return val; +} + +/** + * kfifo_initialized - Check if the fifo is initialized + * @fifo: address of the fifo to check + * + * Return %true if fifo is initialized, otherwise %false. + * Assumes the fifo was 0 before. + */ +#define kfifo_initialized(fifo) ((fifo)->kfifo.mask) + +/** + * kfifo_esize - returns the size of the element managed by the fifo + * @fifo: address of the fifo to be used + */ +#define kfifo_esize(fifo) ((fifo)->kfifo.esize) + +/** + * kfifo_recsize - returns the size of the record length field + * @fifo: address of the fifo to be used + */ +#define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype)) + +/** + * kfifo_size - returns the size of the fifo in elements + * @fifo: address of the fifo to be used + */ +#define kfifo_size(fifo) ((fifo)->kfifo.mask + 1) + +/** + * kfifo_reset - removes the entire fifo content + * @fifo: address of the fifo to be used + * + * Note: usage of kfifo_reset() is dangerous. It should be only called when the + * fifo is exclusived locked or when it is secured that no other thread is + * accessing the fifo. + */ +#define kfifo_reset(fifo) \ +(void)({ \ + typeof(fifo + 1) __tmp = (fifo); \ + __tmp->kfifo.in = __tmp->kfifo.out = 0; \ +}) + +/** + * kfifo_reset_out - skip fifo content + * @fifo: address of the fifo to be used + * + * Note: The usage of kfifo_reset_out() is safe until it will be only called + * from the reader thread and there is only one concurrent reader. Otherwise + * it is dangerous and must be handled in the same way as kfifo_reset(). + */ +#define kfifo_reset_out(fifo) \ +(void)({ \ + typeof(fifo + 1) __tmp = (fifo); \ + __tmp->kfifo.out = __tmp->kfifo.in; \ +}) + +/** + * kfifo_len - returns the number of used elements in the fifo + * @fifo: address of the fifo to be used + */ +#define kfifo_len(fifo) \ +({ \ + typeof(fifo + 1) __tmpl = (fifo); \ + __tmpl->kfifo.in - __tmpl->kfifo.out; \ +}) + +/** + * kfifo_is_empty - returns true if the fifo is empty + * @fifo: address of the fifo to be used + */ +#define kfifo_is_empty(fifo) \ +({ \ + typeof(fifo + 1) __tmpq = (fifo); \ + __tmpq->kfifo.in == __tmpq->kfifo.out; \ +}) + +/** + * kfifo_is_full - returns true if the fifo is full + * @fifo: address of the fifo to be used + */ +#define kfifo_is_full(fifo) \ +({ \ + typeof(fifo + 1) __tmpq = (fifo); \ + kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ +}) + +/** + * kfifo_avail - returns the number of unused elements in the fifo + * @fifo: address of the fifo to be used + */ +#define kfifo_avail(fifo) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmpq = (fifo); \ + const size_t __recsize = sizeof(*__tmpq->rectype); \ + unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ + (__recsize) ? ((__avail <= __recsize) ? 0 : \ + __kfifo_max_r(__avail - __recsize, __recsize)) : \ + __avail; \ +}) \ +) + +/** + * kfifo_skip - skip output data + * @fifo: address of the fifo to be used + */ +#define kfifo_skip(fifo) \ +(void)({ \ + typeof(fifo + 1) __tmp = (fifo); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (__recsize) \ + __kfifo_skip_r(__kfifo, __recsize); \ + else \ + __kfifo->out++; \ +}) + +/** + * kfifo_peek_len - gets the size of the next fifo record + * @fifo: address of the fifo to be used + * + * This function returns the size of the next fifo record in number of bytes. + */ +#define kfifo_peek_len(fifo) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ + __kfifo_len_r(__kfifo, __recsize); \ +}) \ +) + +/** + * kfifo_alloc - dynamically allocates a new fifo buffer + * @fifo: pointer to the fifo + * @size: the number of elements in the fifo, this must be a power of 2 + * @gfp_mask: get_free_pages mask, passed to kmalloc() + * + * This macro dynamically allocates a new fifo buffer. + * + * The numer of elements will be rounded-up to a power of 2. + * The fifo will be release with kfifo_free(). + * Return 0 if no error, otherwise an error code. + */ +#define kfifo_alloc(fifo, size, gfp_mask) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + __is_kfifo_ptr(__tmp) ? \ + __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ + -EINVAL; \ +}) \ +) + +/** + * kfifo_free - frees the fifo + * @fifo: the fifo to be freed + */ +#define kfifo_free(fifo) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (__is_kfifo_ptr(__tmp)) \ + __kfifo_free(__kfifo); \ +}) + +/** + * kfifo_init - initialize a fifo using a preallocated buffer + * @fifo: the fifo to assign the buffer + * @buffer: the preallocated buffer to be used + * @size: the size of the internal buffer, this have to be a power of 2 + * + * This macro initialize a fifo using a preallocated buffer. + * + * The numer of elements will be rounded-up to a power of 2. + * Return 0 if no error, otherwise an error code. + */ +#define kfifo_init(fifo, buffer, size) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + __is_kfifo_ptr(__tmp) ? \ + __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ + -EINVAL; \ +}) + +/** + * kfifo_put - put data into the fifo + * @fifo: address of the fifo to be used + * @val: the data to be added + * + * This macro copies the given value into the fifo. + * It returns 0 if the fifo was full. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_put(fifo, val) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(val + 1) __val = (val); \ + unsigned int __ret; \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ + __dummy = (typeof(__val))NULL; \ + } \ + if (__recsize) \ + __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !kfifo_is_full(__tmp); \ + if (__ret) { \ + (__is_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__kfifo->data) : \ + (__tmp->buf) \ + )[__kfifo->in & __tmp->kfifo.mask] = \ + *(typeof(__tmp->type))__val; \ + smp_wmb(); \ + __kfifo->in++; \ + } \ + } \ + __ret; \ +}) + +/** + * kfifo_get - get data from the fifo + * @fifo: address of the fifo to be used + * @val: the var where to store the data to be added + * + * This macro reads the data from the fifo. + * It returns 0 if the fifo was empty. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_get(fifo, val) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(val + 1) __val = (val); \ + unsigned int __ret; \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) \ + __val = (typeof(__tmp->ptr))0; \ + if (__recsize) \ + __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !kfifo_is_empty(__tmp); \ + if (__ret) { \ + *(typeof(__tmp->type))__val = \ + (__is_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__kfifo->data) : \ + (__tmp->buf) \ + )[__kfifo->out & __tmp->kfifo.mask]; \ + smp_wmb(); \ + __kfifo->out++; \ + } \ + } \ + __ret; \ +}) \ +) + +/** + * kfifo_peek - get data from the fifo without removing + * @fifo: address of the fifo to be used + * @val: the var where to store the data to be added + * + * This reads the data from the fifo without removing it from the fifo. + * It returns 0 if the fifo was empty. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_peek(fifo, val) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(val + 1) __val = (val); \ + unsigned int __ret; \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) \ + __val = (typeof(__tmp->ptr))NULL; \ + if (__recsize) \ + __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !kfifo_is_empty(__tmp); \ + if (__ret) { \ + *(typeof(__tmp->type))__val = \ + (__is_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__kfifo->data) : \ + (__tmp->buf) \ + )[__kfifo->out & __tmp->kfifo.mask]; \ + smp_wmb(); \ + } \ + } \ + __ret; \ +}) \ +) + +/** + * kfifo_in - put data into the fifo + * @fifo: address of the fifo to be used + * @buf: the data to be added + * @n: number of elements to be added + * + * This macro copies the given buffer into the fifo and returns the + * number of copied elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_in(fifo, buf, n) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(buf + 1) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ + __dummy = (typeof(__buf))NULL; \ + } \ + (__recsize) ?\ + __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ + __kfifo_in(__kfifo, __buf, __n); \ +}) + +/** + * kfifo_in_spinlocked - put data into the fifo using a spinlock for locking + * @fifo: address of the fifo to be used + * @buf: the data to be added + * @n: number of elements to be added + * @lock: pointer to the spinlock to use for locking + * + * This macro copies the given values buffer into the fifo and returns the + * number of copied elements. + */ +#define kfifo_in_spinlocked(fifo, buf, n, lock) \ +({ \ + unsigned long __flags; \ + unsigned int __ret; \ + spin_lock_irqsave(lock, __flags); \ + __ret = kfifo_in(fifo, buf, n); \ + spin_unlock_irqrestore(lock, __flags); \ + __ret; \ +}) + +/* alias for kfifo_in_spinlocked, will be removed in a future release */ +#define kfifo_in_locked(fifo, buf, n, lock) \ + kfifo_in_spinlocked(fifo, buf, n, lock) + +/** + * kfifo_out - get data from the fifo + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * + * This macro get some data from the fifo and return the numbers of elements + * copied. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_out(fifo, buf, n) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(buf + 1) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr) __dummy = NULL; \ + __buf = __dummy; \ + } \ + (__recsize) ?\ + __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ + __kfifo_out(__kfifo, __buf, __n); \ +}) \ +) + +/** + * kfifo_out_spinlocked - get data from the fifo using a spinlock for locking + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * @lock: pointer to the spinlock to use for locking + * + * This macro get the data from the fifo and return the numbers of elements + * copied. + */ +#define kfifo_out_spinlocked(fifo, buf, n, lock) \ +__kfifo_must_check_helper( \ +({ \ + unsigned long __flags; \ + unsigned int __ret; \ + spin_lock_irqsave(lock, __flags); \ + __ret = kfifo_out(fifo, buf, n); \ + spin_unlock_irqrestore(lock, __flags); \ + __ret; \ +}) \ +) + +/* alias for kfifo_out_spinlocked, will be removed in a future release */ +#define kfifo_out_locked(fifo, buf, n, lock) \ + kfifo_out_spinlocked(fifo, buf, n, lock) + +/** + * kfifo_from_user - puts some data from user space into the fifo + * @fifo: address of the fifo to be used + * @from: pointer to the data to be added + * @len: the length of the data to be added + * @copied: pointer to output variable to store the number of copied bytes + * + * This macro copies at most @len bytes from the @from into the + * fifo, depending of the available space and returns -EFAULT/0. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_from_user(fifo, from, len, copied) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + const void __user *__from = (from); \ + unsigned int __len = (len); \ + unsigned int *__copied = (copied); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (__recsize) ? \ + __kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \ + __kfifo_from_user(__kfifo, __from, __len, __copied); \ +}) \ +) + +/** + * kfifo_to_user - copies data from the fifo into user space + * @fifo: address of the fifo to be used + * @to: where the data must be copied + * @len: the size of the destination buffer + * @copied: pointer to output variable to store the number of copied bytes + * + * This macro copies at most @len bytes from the fifo into the + * @to buffer and returns -EFAULT/0. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_to_user(fifo, to, len, copied) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + void __user *__to = (to); \ + unsigned int __len = (len); \ + unsigned int *__copied = (copied); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (__recsize) ? \ + __kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \ + __kfifo_to_user(__kfifo, __to, __len, __copied); \ +}) \ +) + +/** + * kfifo_dma_in_prepare - setup a scatterlist for DMA input + * @fifo: address of the fifo to be used + * @sgl: pointer to the scatterlist array + * @nents: number of entries in the scatterlist array + * @len: number of elements to transfer + * + * This macro fills a scatterlist for DMA input. + * It returns the number entries in the scatterlist array. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macros. + */ +#define kfifo_dma_in_prepare(fifo, sgl, nents, len) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + struct scatterlist *__sgl = (sgl); \ + int __nents = (nents); \ + unsigned int __len = (len); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (__recsize) ? \ + __kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ + __kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \ +}) + +/** + * kfifo_dma_in_finish - finish a DMA IN operation + * @fifo: address of the fifo to be used + * @len: number of bytes to received + * + * This macro finish a DMA IN operation. The in counter will be updated by + * the len parameter. No error checking will be done. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macros. + */ +#define kfifo_dma_in_finish(fifo, len) \ +(void)({ \ + typeof(fifo + 1) __tmp = (fifo); \ + unsigned int __len = (len); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (__recsize) \ + __kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \ + else \ + __kfifo->in += __len / sizeof(*__tmp->type); \ +}) + +/** + * kfifo_dma_out_prepare - setup a scatterlist for DMA output + * @fifo: address of the fifo to be used + * @sgl: pointer to the scatterlist array + * @nents: number of entries in the scatterlist array + * @len: number of elements to transfer + * + * This macro fills a scatterlist for DMA output which at most @len bytes + * to transfer. + * It returns the number entries in the scatterlist array. + * A zero means there is no space available and the scatterlist is not filled. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macros. + */ +#define kfifo_dma_out_prepare(fifo, sgl, nents, len) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + struct scatterlist *__sgl = (sgl); \ + int __nents = (nents); \ + unsigned int __len = (len); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (__recsize) ? \ + __kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ + __kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \ +}) + +/** + * kfifo_dma_out_finish - finish a DMA OUT operation + * @fifo: address of the fifo to be used + * @len: number of bytes transferd + * + * This macro finish a DMA OUT operation. The out counter will be updated by + * the len parameter. No error checking will be done. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macros. + */ +#define kfifo_dma_out_finish(fifo, len) \ +(void)({ \ + typeof(fifo + 1) __tmp = (fifo); \ + unsigned int __len = (len); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (__recsize) \ + __kfifo_dma_out_finish_r(__kfifo, __recsize); \ + else \ + __kfifo->out += __len / sizeof(*__tmp->type); \ +}) + +/** + * kfifo_out_peek - gets some data from the fifo + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * + * This macro get the data from the fifo and return the numbers of elements + * copied. The data is not removed from the fifo. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_out_peek(fifo, buf, n) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(buf + 1) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ + __buf = __dummy; \ + } \ + (__recsize) ? \ + __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ + __kfifo_out_peek(__kfifo, __buf, __n); \ +}) \ +) + +extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, + size_t esize, gfp_t gfp_mask); + +extern void __kfifo_free(struct __kfifo *fifo); + +extern int __kfifo_init(struct __kfifo *fifo, void *buffer, + unsigned int size, size_t esize); + +extern unsigned int __kfifo_in(struct __kfifo *fifo, + const void *buf, unsigned int len); + +extern unsigned int __kfifo_out(struct __kfifo *fifo, + void *buf, unsigned int len); + +extern int __kfifo_from_user(struct __kfifo *fifo, + const void __user *from, unsigned long len, unsigned int *copied); + +extern int __kfifo_to_user(struct __kfifo *fifo, + void __user *to, unsigned long len, unsigned int *copied); + +extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo, + struct scatterlist *sgl, int nents, unsigned int len); + +extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo, + struct scatterlist *sgl, int nents, unsigned int len); + +extern unsigned int __kfifo_out_peek(struct __kfifo *fifo, + void *buf, unsigned int len); + +extern unsigned int __kfifo_in_r(struct __kfifo *fifo, + const void *buf, unsigned int len, size_t recsize); + +extern unsigned int __kfifo_out_r(struct __kfifo *fifo, + void *buf, unsigned int len, size_t recsize); + +extern int __kfifo_from_user_r(struct __kfifo *fifo, + const void __user *from, unsigned long len, unsigned int *copied, + size_t recsize); + +extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to, + unsigned long len, unsigned int *copied, size_t recsize); + +extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo, + struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); + +extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo, + unsigned int len, size_t recsize); + +extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo, + struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); + +extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize); + +extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize); + +extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, + void *buf, unsigned int len, size_t recsize); + +extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize); + +#endif -- cgit v1.1 From 2e956fb320568cc70861761483e2f0e2db75fd66 Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Tue, 10 Aug 2010 18:03:38 -0700 Subject: kfifo: replace the old non generic API Simply replace the whole kfifo.c and kfifo.h files with the new generic version and fix the kerneldoc API template file. Signed-off-by: Stefani Seibold Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kfifo-new.h | 844 -------------------------------- include/linux/kfifo.h | 1193 +++++++++++++++++++++++++++------------------ 2 files changed, 711 insertions(+), 1326 deletions(-) delete mode 100644 include/linux/kfifo-new.h (limited to 'include') diff --git a/include/linux/kfifo-new.h b/include/linux/kfifo-new.h deleted file mode 100644 index 311f875..0000000 --- a/include/linux/kfifo-new.h +++ /dev/null @@ -1,844 +0,0 @@ -/* - * A generic kernel FIFO implementation - * - * Copyright (C) 2009/2010 Stefani Seibold - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _LINUX_KFIFO_H -#define _LINUX_KFIFO_H - -/* - * How to porting drivers to the new generic FIFO API: - * - * - Modify the declaration of the "struct kfifo *" object into a - * in-place "struct kfifo" object - * - Init the in-place object with kfifo_alloc() or kfifo_init() - * Note: The address of the in-place "struct kfifo" object must be - * passed as the first argument to this functions - * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get - * into kfifo_out - * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get - * into kfifo_out_spinlocked - * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc - * must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked - * as the last parameter - * - The formerly __kfifo_* functions are renamed into kfifo_* - */ - -/* - * Note about locking : There is no locking required until only * one reader - * and one writer is using the fifo and no kfifo_reset() will be * called - * kfifo_reset_out() can be safely used, until it will be only called - * in the reader thread. - * For multiple writer and one reader there is only a need to lock the writer. - * And vice versa for only one writer and multiple reader there is only a need - * to lock the reader. - */ - -#include -#include -#include -#include - -struct __kfifo { - unsigned int in; - unsigned int out; - unsigned int mask; - unsigned int esize; - void *data; -}; - -#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ - union { \ - struct __kfifo kfifo; \ - datatype *type; \ - char (*rectype)[recsize]; \ - ptrtype *ptr; \ - const ptrtype *ptr_const; \ - } - -#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ -{ \ - __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ - type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ -} - -#define STRUCT_KFIFO(type, size) \ - struct __STRUCT_KFIFO(type, size, 0, type) - -#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ -{ \ - __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ - type buf[0]; \ -} - -#define STRUCT_KFIFO_PTR(type) \ - struct __STRUCT_KFIFO_PTR(type, 0, type) - -/* - * define compatibility "struct kfifo" for dynamic allocated fifos - */ -struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); - -#define STRUCT_KFIFO_REC_1(size) \ - struct __STRUCT_KFIFO(unsigned char, size, 1, void) - -#define STRUCT_KFIFO_REC_2(size) \ - struct __STRUCT_KFIFO(unsigned char, size, 2, void) - -/* - * define kfifo_rec types - */ -struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); -struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); - -/* - * helper macro to distinguish between real in place fifo where the fifo - * array is a part of the structure and the fifo type where the array is - * outside of the fifo structure. - */ -#define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo)) - -/** - * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object - * @fifo: name of the declared fifo - * @type: type of the fifo elements - */ -#define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo - -/** - * DECLARE_KFIFO - macro to declare a fifo object - * @fifo: name of the declared fifo - * @type: type of the fifo elements - * @size: the number of elements in the fifo, this must be a power of 2 - */ -#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo - -/** - * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO - * @fifo: name of the declared fifo datatype - */ -#define INIT_KFIFO(fifo) \ -(void)({ \ - typeof(&(fifo)) __tmp = &(fifo); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - __kfifo->in = 0; \ - __kfifo->out = 0; \ - __kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ - __kfifo->esize = sizeof(*__tmp->buf); \ - __kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \ -}) - -/** - * DEFINE_KFIFO - macro to define and initialize a fifo - * @fifo: name of the declared fifo datatype - * @type: type of the fifo elements - * @size: the number of elements in the fifo, this must be a power of 2 - * - * Note: the macro can be used for global and local fifo data type variables. - */ -#define DEFINE_KFIFO(fifo, type, size) \ - DECLARE_KFIFO(fifo, type, size) = \ - (typeof(fifo)) { \ - { \ - { \ - .in = 0, \ - .out = 0, \ - .mask = __is_kfifo_ptr(&(fifo)) ? \ - 0 : \ - ARRAY_SIZE((fifo).buf) - 1, \ - .esize = sizeof(*(fifo).buf), \ - .data = __is_kfifo_ptr(&(fifo)) ? \ - NULL : \ - (fifo).buf, \ - } \ - } \ - } - - -static inline unsigned int __must_check -__kfifo_must_check_helper(unsigned int val) -{ - return val; -} - -/** - * kfifo_initialized - Check if the fifo is initialized - * @fifo: address of the fifo to check - * - * Return %true if fifo is initialized, otherwise %false. - * Assumes the fifo was 0 before. - */ -#define kfifo_initialized(fifo) ((fifo)->kfifo.mask) - -/** - * kfifo_esize - returns the size of the element managed by the fifo - * @fifo: address of the fifo to be used - */ -#define kfifo_esize(fifo) ((fifo)->kfifo.esize) - -/** - * kfifo_recsize - returns the size of the record length field - * @fifo: address of the fifo to be used - */ -#define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype)) - -/** - * kfifo_size - returns the size of the fifo in elements - * @fifo: address of the fifo to be used - */ -#define kfifo_size(fifo) ((fifo)->kfifo.mask + 1) - -/** - * kfifo_reset - removes the entire fifo content - * @fifo: address of the fifo to be used - * - * Note: usage of kfifo_reset() is dangerous. It should be only called when the - * fifo is exclusived locked or when it is secured that no other thread is - * accessing the fifo. - */ -#define kfifo_reset(fifo) \ -(void)({ \ - typeof(fifo + 1) __tmp = (fifo); \ - __tmp->kfifo.in = __tmp->kfifo.out = 0; \ -}) - -/** - * kfifo_reset_out - skip fifo content - * @fifo: address of the fifo to be used - * - * Note: The usage of kfifo_reset_out() is safe until it will be only called - * from the reader thread and there is only one concurrent reader. Otherwise - * it is dangerous and must be handled in the same way as kfifo_reset(). - */ -#define kfifo_reset_out(fifo) \ -(void)({ \ - typeof(fifo + 1) __tmp = (fifo); \ - __tmp->kfifo.out = __tmp->kfifo.in; \ -}) - -/** - * kfifo_len - returns the number of used elements in the fifo - * @fifo: address of the fifo to be used - */ -#define kfifo_len(fifo) \ -({ \ - typeof(fifo + 1) __tmpl = (fifo); \ - __tmpl->kfifo.in - __tmpl->kfifo.out; \ -}) - -/** - * kfifo_is_empty - returns true if the fifo is empty - * @fifo: address of the fifo to be used - */ -#define kfifo_is_empty(fifo) \ -({ \ - typeof(fifo + 1) __tmpq = (fifo); \ - __tmpq->kfifo.in == __tmpq->kfifo.out; \ -}) - -/** - * kfifo_is_full - returns true if the fifo is full - * @fifo: address of the fifo to be used - */ -#define kfifo_is_full(fifo) \ -({ \ - typeof(fifo + 1) __tmpq = (fifo); \ - kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ -}) - -/** - * kfifo_avail - returns the number of unused elements in the fifo - * @fifo: address of the fifo to be used - */ -#define kfifo_avail(fifo) \ -__kfifo_must_check_helper( \ -({ \ - typeof(fifo + 1) __tmpq = (fifo); \ - const size_t __recsize = sizeof(*__tmpq->rectype); \ - unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ - (__recsize) ? ((__avail <= __recsize) ? 0 : \ - __kfifo_max_r(__avail - __recsize, __recsize)) : \ - __avail; \ -}) \ -) - -/** - * kfifo_skip - skip output data - * @fifo: address of the fifo to be used - */ -#define kfifo_skip(fifo) \ -(void)({ \ - typeof(fifo + 1) __tmp = (fifo); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (__recsize) \ - __kfifo_skip_r(__kfifo, __recsize); \ - else \ - __kfifo->out++; \ -}) - -/** - * kfifo_peek_len - gets the size of the next fifo record - * @fifo: address of the fifo to be used - * - * This function returns the size of the next fifo record in number of bytes. - */ -#define kfifo_peek_len(fifo) \ -__kfifo_must_check_helper( \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ - __kfifo_len_r(__kfifo, __recsize); \ -}) \ -) - -/** - * kfifo_alloc - dynamically allocates a new fifo buffer - * @fifo: pointer to the fifo - * @size: the number of elements in the fifo, this must be a power of 2 - * @gfp_mask: get_free_pages mask, passed to kmalloc() - * - * This macro dynamically allocates a new fifo buffer. - * - * The numer of elements will be rounded-up to a power of 2. - * The fifo will be release with kfifo_free(). - * Return 0 if no error, otherwise an error code. - */ -#define kfifo_alloc(fifo, size, gfp_mask) \ -__kfifo_must_check_helper( \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - __is_kfifo_ptr(__tmp) ? \ - __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ - -EINVAL; \ -}) \ -) - -/** - * kfifo_free - frees the fifo - * @fifo: the fifo to be freed - */ -#define kfifo_free(fifo) \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (__is_kfifo_ptr(__tmp)) \ - __kfifo_free(__kfifo); \ -}) - -/** - * kfifo_init - initialize a fifo using a preallocated buffer - * @fifo: the fifo to assign the buffer - * @buffer: the preallocated buffer to be used - * @size: the size of the internal buffer, this have to be a power of 2 - * - * This macro initialize a fifo using a preallocated buffer. - * - * The numer of elements will be rounded-up to a power of 2. - * Return 0 if no error, otherwise an error code. - */ -#define kfifo_init(fifo, buffer, size) \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - __is_kfifo_ptr(__tmp) ? \ - __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ - -EINVAL; \ -}) - -/** - * kfifo_put - put data into the fifo - * @fifo: address of the fifo to be used - * @val: the data to be added - * - * This macro copies the given value into the fifo. - * It returns 0 if the fifo was full. Otherwise it returns the number - * processed elements. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_put(fifo, val) \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - typeof(val + 1) __val = (val); \ - unsigned int __ret; \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ - __dummy = (typeof(__val))NULL; \ - } \ - if (__recsize) \ - __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ - __recsize); \ - else { \ - __ret = !kfifo_is_full(__tmp); \ - if (__ret) { \ - (__is_kfifo_ptr(__tmp) ? \ - ((typeof(__tmp->type))__kfifo->data) : \ - (__tmp->buf) \ - )[__kfifo->in & __tmp->kfifo.mask] = \ - *(typeof(__tmp->type))__val; \ - smp_wmb(); \ - __kfifo->in++; \ - } \ - } \ - __ret; \ -}) - -/** - * kfifo_get - get data from the fifo - * @fifo: address of the fifo to be used - * @val: the var where to store the data to be added - * - * This macro reads the data from the fifo. - * It returns 0 if the fifo was empty. Otherwise it returns the number - * processed elements. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_get(fifo, val) \ -__kfifo_must_check_helper( \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - typeof(val + 1) __val = (val); \ - unsigned int __ret; \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) \ - __val = (typeof(__tmp->ptr))0; \ - if (__recsize) \ - __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ - __recsize); \ - else { \ - __ret = !kfifo_is_empty(__tmp); \ - if (__ret) { \ - *(typeof(__tmp->type))__val = \ - (__is_kfifo_ptr(__tmp) ? \ - ((typeof(__tmp->type))__kfifo->data) : \ - (__tmp->buf) \ - )[__kfifo->out & __tmp->kfifo.mask]; \ - smp_wmb(); \ - __kfifo->out++; \ - } \ - } \ - __ret; \ -}) \ -) - -/** - * kfifo_peek - get data from the fifo without removing - * @fifo: address of the fifo to be used - * @val: the var where to store the data to be added - * - * This reads the data from the fifo without removing it from the fifo. - * It returns 0 if the fifo was empty. Otherwise it returns the number - * processed elements. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_peek(fifo, val) \ -__kfifo_must_check_helper( \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - typeof(val + 1) __val = (val); \ - unsigned int __ret; \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) \ - __val = (typeof(__tmp->ptr))NULL; \ - if (__recsize) \ - __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ - __recsize); \ - else { \ - __ret = !kfifo_is_empty(__tmp); \ - if (__ret) { \ - *(typeof(__tmp->type))__val = \ - (__is_kfifo_ptr(__tmp) ? \ - ((typeof(__tmp->type))__kfifo->data) : \ - (__tmp->buf) \ - )[__kfifo->out & __tmp->kfifo.mask]; \ - smp_wmb(); \ - } \ - } \ - __ret; \ -}) \ -) - -/** - * kfifo_in - put data into the fifo - * @fifo: address of the fifo to be used - * @buf: the data to be added - * @n: number of elements to be added - * - * This macro copies the given buffer into the fifo and returns the - * number of copied elements. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_in(fifo, buf, n) \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - typeof(buf + 1) __buf = (buf); \ - unsigned long __n = (n); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ - __dummy = (typeof(__buf))NULL; \ - } \ - (__recsize) ?\ - __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ - __kfifo_in(__kfifo, __buf, __n); \ -}) - -/** - * kfifo_in_spinlocked - put data into the fifo using a spinlock for locking - * @fifo: address of the fifo to be used - * @buf: the data to be added - * @n: number of elements to be added - * @lock: pointer to the spinlock to use for locking - * - * This macro copies the given values buffer into the fifo and returns the - * number of copied elements. - */ -#define kfifo_in_spinlocked(fifo, buf, n, lock) \ -({ \ - unsigned long __flags; \ - unsigned int __ret; \ - spin_lock_irqsave(lock, __flags); \ - __ret = kfifo_in(fifo, buf, n); \ - spin_unlock_irqrestore(lock, __flags); \ - __ret; \ -}) - -/* alias for kfifo_in_spinlocked, will be removed in a future release */ -#define kfifo_in_locked(fifo, buf, n, lock) \ - kfifo_in_spinlocked(fifo, buf, n, lock) - -/** - * kfifo_out - get data from the fifo - * @fifo: address of the fifo to be used - * @buf: pointer to the storage buffer - * @n: max. number of elements to get - * - * This macro get some data from the fifo and return the numbers of elements - * copied. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_out(fifo, buf, n) \ -__kfifo_must_check_helper( \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - typeof(buf + 1) __buf = (buf); \ - unsigned long __n = (n); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr) __dummy = NULL; \ - __buf = __dummy; \ - } \ - (__recsize) ?\ - __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ - __kfifo_out(__kfifo, __buf, __n); \ -}) \ -) - -/** - * kfifo_out_spinlocked - get data from the fifo using a spinlock for locking - * @fifo: address of the fifo to be used - * @buf: pointer to the storage buffer - * @n: max. number of elements to get - * @lock: pointer to the spinlock to use for locking - * - * This macro get the data from the fifo and return the numbers of elements - * copied. - */ -#define kfifo_out_spinlocked(fifo, buf, n, lock) \ -__kfifo_must_check_helper( \ -({ \ - unsigned long __flags; \ - unsigned int __ret; \ - spin_lock_irqsave(lock, __flags); \ - __ret = kfifo_out(fifo, buf, n); \ - spin_unlock_irqrestore(lock, __flags); \ - __ret; \ -}) \ -) - -/* alias for kfifo_out_spinlocked, will be removed in a future release */ -#define kfifo_out_locked(fifo, buf, n, lock) \ - kfifo_out_spinlocked(fifo, buf, n, lock) - -/** - * kfifo_from_user - puts some data from user space into the fifo - * @fifo: address of the fifo to be used - * @from: pointer to the data to be added - * @len: the length of the data to be added - * @copied: pointer to output variable to store the number of copied bytes - * - * This macro copies at most @len bytes from the @from into the - * fifo, depending of the available space and returns -EFAULT/0. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_from_user(fifo, from, len, copied) \ -__kfifo_must_check_helper( \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - const void __user *__from = (from); \ - unsigned int __len = (len); \ - unsigned int *__copied = (copied); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (__recsize) ? \ - __kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \ - __kfifo_from_user(__kfifo, __from, __len, __copied); \ -}) \ -) - -/** - * kfifo_to_user - copies data from the fifo into user space - * @fifo: address of the fifo to be used - * @to: where the data must be copied - * @len: the size of the destination buffer - * @copied: pointer to output variable to store the number of copied bytes - * - * This macro copies at most @len bytes from the fifo into the - * @to buffer and returns -EFAULT/0. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_to_user(fifo, to, len, copied) \ -__kfifo_must_check_helper( \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - void __user *__to = (to); \ - unsigned int __len = (len); \ - unsigned int *__copied = (copied); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (__recsize) ? \ - __kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \ - __kfifo_to_user(__kfifo, __to, __len, __copied); \ -}) \ -) - -/** - * kfifo_dma_in_prepare - setup a scatterlist for DMA input - * @fifo: address of the fifo to be used - * @sgl: pointer to the scatterlist array - * @nents: number of entries in the scatterlist array - * @len: number of elements to transfer - * - * This macro fills a scatterlist for DMA input. - * It returns the number entries in the scatterlist array. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macros. - */ -#define kfifo_dma_in_prepare(fifo, sgl, nents, len) \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - struct scatterlist *__sgl = (sgl); \ - int __nents = (nents); \ - unsigned int __len = (len); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (__recsize) ? \ - __kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ - __kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \ -}) - -/** - * kfifo_dma_in_finish - finish a DMA IN operation - * @fifo: address of the fifo to be used - * @len: number of bytes to received - * - * This macro finish a DMA IN operation. The in counter will be updated by - * the len parameter. No error checking will be done. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macros. - */ -#define kfifo_dma_in_finish(fifo, len) \ -(void)({ \ - typeof(fifo + 1) __tmp = (fifo); \ - unsigned int __len = (len); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (__recsize) \ - __kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \ - else \ - __kfifo->in += __len / sizeof(*__tmp->type); \ -}) - -/** - * kfifo_dma_out_prepare - setup a scatterlist for DMA output - * @fifo: address of the fifo to be used - * @sgl: pointer to the scatterlist array - * @nents: number of entries in the scatterlist array - * @len: number of elements to transfer - * - * This macro fills a scatterlist for DMA output which at most @len bytes - * to transfer. - * It returns the number entries in the scatterlist array. - * A zero means there is no space available and the scatterlist is not filled. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macros. - */ -#define kfifo_dma_out_prepare(fifo, sgl, nents, len) \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - struct scatterlist *__sgl = (sgl); \ - int __nents = (nents); \ - unsigned int __len = (len); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - (__recsize) ? \ - __kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ - __kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \ -}) - -/** - * kfifo_dma_out_finish - finish a DMA OUT operation - * @fifo: address of the fifo to be used - * @len: number of bytes transferd - * - * This macro finish a DMA OUT operation. The out counter will be updated by - * the len parameter. No error checking will be done. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macros. - */ -#define kfifo_dma_out_finish(fifo, len) \ -(void)({ \ - typeof(fifo + 1) __tmp = (fifo); \ - unsigned int __len = (len); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (__recsize) \ - __kfifo_dma_out_finish_r(__kfifo, __recsize); \ - else \ - __kfifo->out += __len / sizeof(*__tmp->type); \ -}) - -/** - * kfifo_out_peek - gets some data from the fifo - * @fifo: address of the fifo to be used - * @buf: pointer to the storage buffer - * @n: max. number of elements to get - * - * This macro get the data from the fifo and return the numbers of elements - * copied. The data is not removed from the fifo. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these macro. - */ -#define kfifo_out_peek(fifo, buf, n) \ -__kfifo_must_check_helper( \ -({ \ - typeof(fifo + 1) __tmp = (fifo); \ - typeof(buf + 1) __buf = (buf); \ - unsigned long __n = (n); \ - const size_t __recsize = sizeof(*__tmp->rectype); \ - struct __kfifo *__kfifo = &__tmp->kfifo; \ - if (0) { \ - typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ - __buf = __dummy; \ - } \ - (__recsize) ? \ - __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ - __kfifo_out_peek(__kfifo, __buf, __n); \ -}) \ -) - -extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, - size_t esize, gfp_t gfp_mask); - -extern void __kfifo_free(struct __kfifo *fifo); - -extern int __kfifo_init(struct __kfifo *fifo, void *buffer, - unsigned int size, size_t esize); - -extern unsigned int __kfifo_in(struct __kfifo *fifo, - const void *buf, unsigned int len); - -extern unsigned int __kfifo_out(struct __kfifo *fifo, - void *buf, unsigned int len); - -extern int __kfifo_from_user(struct __kfifo *fifo, - const void __user *from, unsigned long len, unsigned int *copied); - -extern int __kfifo_to_user(struct __kfifo *fifo, - void __user *to, unsigned long len, unsigned int *copied); - -extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo, - struct scatterlist *sgl, int nents, unsigned int len); - -extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo, - struct scatterlist *sgl, int nents, unsigned int len); - -extern unsigned int __kfifo_out_peek(struct __kfifo *fifo, - void *buf, unsigned int len); - -extern unsigned int __kfifo_in_r(struct __kfifo *fifo, - const void *buf, unsigned int len, size_t recsize); - -extern unsigned int __kfifo_out_r(struct __kfifo *fifo, - void *buf, unsigned int len, size_t recsize); - -extern int __kfifo_from_user_r(struct __kfifo *fifo, - const void __user *from, unsigned long len, unsigned int *copied, - size_t recsize); - -extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to, - unsigned long len, unsigned int *copied, size_t recsize); - -extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo, - struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); - -extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo, - unsigned int len, size_t recsize); - -extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo, - struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); - -extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize); - -extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize); - -extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, - void *buf, unsigned int len, size_t recsize); - -extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize); - -#endif diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 57c4eed..311f875 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -1,8 +1,7 @@ /* - * A generic kernel FIFO implementation. + * A generic kernel FIFO implementation * - * Copyright (C) 2009 Stefani Seibold - * Copyright (C) 2004 Stelian Pop + * Copyright (C) 2009/2010 Stefani Seibold * * 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 @@ -20,8 +19,11 @@ * */ +#ifndef _LINUX_KFIFO_H +#define _LINUX_KFIFO_H + /* - * Howto porting drivers to the new generic fifo API: + * How to porting drivers to the new generic FIFO API: * * - Modify the declaration of the "struct kfifo *" object into a * in-place "struct kfifo" object @@ -30,586 +32,813 @@ * passed as the first argument to this functions * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get * into kfifo_out - * - Replace the use of kfifo_put into kfifo_in_locked and kfifo_get - * into kfifo_out_locked + * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get + * into kfifo_out_spinlocked * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc - * must be passed now to the kfifo_in_locked and kfifo_out_locked - * as the last parameter. - * - All formerly name __kfifo_* functions has been renamed into kfifo_* + * must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked + * as the last parameter + * - The formerly __kfifo_* functions are renamed into kfifo_* */ -#ifndef _LINUX_KFIFO_H -#define _LINUX_KFIFO_H +/* + * Note about locking : There is no locking required until only * one reader + * and one writer is using the fifo and no kfifo_reset() will be * called + * kfifo_reset_out() can be safely used, until it will be only called + * in the reader thread. + * For multiple writer and one reader there is only a need to lock the writer. + * And vice versa for only one writer and multiple reader there is only a need + * to lock the reader. + */ #include #include - -struct kfifo { - unsigned char *buffer; /* the buffer holding the data */ - unsigned int size; /* the size of the allocated buffer */ - unsigned int in; /* data is added at offset (in % size) */ - unsigned int out; /* data is extracted from off. (out % size) */ +#include +#include + +struct __kfifo { + unsigned int in; + unsigned int out; + unsigned int mask; + unsigned int esize; + void *data; }; -/* - * Macros for declaration and initialization of the kfifo datatype - */ - -/* helper macro */ -#define __kfifo_initializer(s, b) \ - (struct kfifo) { \ - .size = s, \ - .in = 0, \ - .out = 0, \ - .buffer = b \ +#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ + union { \ + struct __kfifo kfifo; \ + datatype *type; \ + char (*rectype)[recsize]; \ + ptrtype *ptr; \ + const ptrtype *ptr_const; \ } -/** - * DECLARE_KFIFO - macro to declare a kfifo and the associated buffer - * @name: name of the declared kfifo datatype - * @size: size of the fifo buffer. Must be a power of two. - * - * Note1: the macro can be used inside struct or union declaration - * Note2: the macro creates two objects: - * A kfifo object with the given name and a buffer for the kfifo - * object named name##kfifo_buffer - */ -#define DECLARE_KFIFO(name, size) \ -union { \ - struct kfifo name; \ - unsigned char name##kfifo_buffer[size + sizeof(struct kfifo)]; \ +#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ +{ \ + __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ + type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ } -/** - * INIT_KFIFO - Initialize a kfifo declared by DECLARE_KFIFO - * @name: name of the declared kfifo datatype +#define STRUCT_KFIFO(type, size) \ + struct __STRUCT_KFIFO(type, size, 0, type) + +#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ +{ \ + __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ + type buf[0]; \ +} + +#define STRUCT_KFIFO_PTR(type) \ + struct __STRUCT_KFIFO_PTR(type, 0, type) + +/* + * define compatibility "struct kfifo" for dynamic allocated fifos */ -#define INIT_KFIFO(name) \ - name = __kfifo_initializer(sizeof(name##kfifo_buffer) - \ - sizeof(struct kfifo), \ - name##kfifo_buffer + sizeof(struct kfifo)) +struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); -/** - * DEFINE_KFIFO - macro to define and initialize a kfifo - * @name: name of the declared kfifo datatype - * @size: size of the fifo buffer. Must be a power of two. - * - * Note1: the macro can be used for global and local kfifo data type variables - * Note2: the macro creates two objects: - * A kfifo object with the given name and a buffer for the kfifo - * object named name##kfifo_buffer +#define STRUCT_KFIFO_REC_1(size) \ + struct __STRUCT_KFIFO(unsigned char, size, 1, void) + +#define STRUCT_KFIFO_REC_2(size) \ + struct __STRUCT_KFIFO(unsigned char, size, 2, void) + +/* + * define kfifo_rec types */ -#define DEFINE_KFIFO(name, size) \ - unsigned char name##kfifo_buffer[size]; \ - struct kfifo name = __kfifo_initializer(size, name##kfifo_buffer) +struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); +struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); -extern void kfifo_init(struct kfifo *fifo, void *buffer, - unsigned int size); -extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size, - gfp_t gfp_mask); -extern void kfifo_free(struct kfifo *fifo); -extern unsigned int kfifo_in(struct kfifo *fifo, - const void *from, unsigned int len); -extern __must_check unsigned int kfifo_out(struct kfifo *fifo, - void *to, unsigned int len); -extern __must_check unsigned int kfifo_out_peek(struct kfifo *fifo, - void *to, unsigned int len, unsigned offset); +/* + * helper macro to distinguish between real in place fifo where the fifo + * array is a part of the structure and the fifo type where the array is + * outside of the fifo structure. + */ +#define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo)) /** - * kfifo_initialized - Check if kfifo is initialized. - * @fifo: fifo to check - * Return %true if FIFO is initialized, otherwise %false. - * Assumes the fifo was 0 before. + * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object + * @fifo: name of the declared fifo + * @type: type of the fifo elements */ -static inline bool kfifo_initialized(struct kfifo *fifo) -{ - return fifo->buffer != NULL; -} +#define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo /** - * kfifo_reset - removes the entire FIFO contents - * @fifo: the fifo to be emptied. + * DECLARE_KFIFO - macro to declare a fifo object + * @fifo: name of the declared fifo + * @type: type of the fifo elements + * @size: the number of elements in the fifo, this must be a power of 2 */ -static inline void kfifo_reset(struct kfifo *fifo) -{ - fifo->in = fifo->out = 0; -} +#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo /** - * kfifo_reset_out - skip FIFO contents - * @fifo: the fifo to be emptied. - */ -static inline void kfifo_reset_out(struct kfifo *fifo) -{ - smp_mb(); - fifo->out = fifo->in; -} + * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO + * @fifo: name of the declared fifo datatype + */ +#define INIT_KFIFO(fifo) \ +(void)({ \ + typeof(&(fifo)) __tmp = &(fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + __kfifo->in = 0; \ + __kfifo->out = 0; \ + __kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ + __kfifo->esize = sizeof(*__tmp->buf); \ + __kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \ +}) /** - * kfifo_size - returns the size of the fifo in bytes - * @fifo: the fifo to be used. - */ -static inline __must_check unsigned int kfifo_size(struct kfifo *fifo) + * DEFINE_KFIFO - macro to define and initialize a fifo + * @fifo: name of the declared fifo datatype + * @type: type of the fifo elements + * @size: the number of elements in the fifo, this must be a power of 2 + * + * Note: the macro can be used for global and local fifo data type variables. + */ +#define DEFINE_KFIFO(fifo, type, size) \ + DECLARE_KFIFO(fifo, type, size) = \ + (typeof(fifo)) { \ + { \ + { \ + .in = 0, \ + .out = 0, \ + .mask = __is_kfifo_ptr(&(fifo)) ? \ + 0 : \ + ARRAY_SIZE((fifo).buf) - 1, \ + .esize = sizeof(*(fifo).buf), \ + .data = __is_kfifo_ptr(&(fifo)) ? \ + NULL : \ + (fifo).buf, \ + } \ + } \ + } + + +static inline unsigned int __must_check +__kfifo_must_check_helper(unsigned int val) { - return fifo->size; + return val; } /** - * kfifo_len - returns the number of used bytes in the FIFO - * @fifo: the fifo to be used. + * kfifo_initialized - Check if the fifo is initialized + * @fifo: address of the fifo to check + * + * Return %true if fifo is initialized, otherwise %false. + * Assumes the fifo was 0 before. */ -static inline unsigned int kfifo_len(struct kfifo *fifo) -{ - register unsigned int out; - - out = fifo->out; - smp_rmb(); - return fifo->in - out; -} +#define kfifo_initialized(fifo) ((fifo)->kfifo.mask) /** - * kfifo_is_empty - returns true if the fifo is empty - * @fifo: the fifo to be used. + * kfifo_esize - returns the size of the element managed by the fifo + * @fifo: address of the fifo to be used */ -static inline __must_check bool kfifo_is_empty(struct kfifo *fifo) -{ - return fifo->in == fifo->out; -} +#define kfifo_esize(fifo) ((fifo)->kfifo.esize) /** - * kfifo_is_full - returns true if the fifo is full - * @fifo: the fifo to be used. + * kfifo_recsize - returns the size of the record length field + * @fifo: address of the fifo to be used */ -static inline __must_check bool kfifo_is_full(struct kfifo *fifo) -{ - return kfifo_len(fifo) == kfifo_size(fifo); -} +#define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype)) /** - * kfifo_avail - returns the number of bytes available in the FIFO - * @fifo: the fifo to be used. + * kfifo_size - returns the size of the fifo in elements + * @fifo: address of the fifo to be used */ -static inline __must_check unsigned int kfifo_avail(struct kfifo *fifo) -{ - return kfifo_size(fifo) - kfifo_len(fifo); -} +#define kfifo_size(fifo) ((fifo)->kfifo.mask + 1) /** - * kfifo_in_locked - puts some data into the FIFO using a spinlock for locking - * @fifo: the fifo to be used. - * @from: the data to be added. - * @n: the length of the data to be added. - * @lock: pointer to the spinlock to use for locking. + * kfifo_reset - removes the entire fifo content + * @fifo: address of the fifo to be used * - * This function copies at most @n bytes from the @from buffer into - * the FIFO depending on the free space, and returns the number of - * bytes copied. + * Note: usage of kfifo_reset() is dangerous. It should be only called when the + * fifo is exclusived locked or when it is secured that no other thread is + * accessing the fifo. */ -static inline unsigned int kfifo_in_locked(struct kfifo *fifo, - const void *from, unsigned int n, spinlock_t *lock) -{ - unsigned long flags; - unsigned int ret; - - spin_lock_irqsave(lock, flags); - - ret = kfifo_in(fifo, from, n); - - spin_unlock_irqrestore(lock, flags); - - return ret; -} +#define kfifo_reset(fifo) \ +(void)({ \ + typeof(fifo + 1) __tmp = (fifo); \ + __tmp->kfifo.in = __tmp->kfifo.out = 0; \ +}) /** - * kfifo_out_locked - gets some data from the FIFO using a spinlock for locking - * @fifo: the fifo to be used. - * @to: where the data must be copied. - * @n: the size of the destination buffer. - * @lock: pointer to the spinlock to use for locking. + * kfifo_reset_out - skip fifo content + * @fifo: address of the fifo to be used * - * This function copies at most @n bytes from the FIFO into the - * @to buffer and returns the number of copied bytes. - */ -static inline __must_check unsigned int kfifo_out_locked(struct kfifo *fifo, - void *to, unsigned int n, spinlock_t *lock) -{ - unsigned long flags; - unsigned int ret; - - spin_lock_irqsave(lock, flags); - - ret = kfifo_out(fifo, to, n); - - spin_unlock_irqrestore(lock, flags); - - return ret; -} - -extern void kfifo_skip(struct kfifo *fifo, unsigned int len); - -extern __must_check int kfifo_from_user(struct kfifo *fifo, - const void __user *from, unsigned int n, unsigned *lenout); - -extern __must_check int kfifo_to_user(struct kfifo *fifo, - void __user *to, unsigned int n, unsigned *lenout); - -/* - * __kfifo_add_out internal helper function for updating the out offset + * Note: The usage of kfifo_reset_out() is safe until it will be only called + * from the reader thread and there is only one concurrent reader. Otherwise + * it is dangerous and must be handled in the same way as kfifo_reset(). */ -static inline void __kfifo_add_out(struct kfifo *fifo, - unsigned int off) -{ - smp_mb(); - fifo->out += off; -} +#define kfifo_reset_out(fifo) \ +(void)({ \ + typeof(fifo + 1) __tmp = (fifo); \ + __tmp->kfifo.out = __tmp->kfifo.in; \ +}) -/* - * __kfifo_add_in internal helper function for updating the in offset +/** + * kfifo_len - returns the number of used elements in the fifo + * @fifo: address of the fifo to be used */ -static inline void __kfifo_add_in(struct kfifo *fifo, - unsigned int off) -{ - smp_wmb(); - fifo->in += off; -} +#define kfifo_len(fifo) \ +({ \ + typeof(fifo + 1) __tmpl = (fifo); \ + __tmpl->kfifo.in - __tmpl->kfifo.out; \ +}) -/* - * __kfifo_off internal helper function for calculating the index of a - * given offeset +/** + * kfifo_is_empty - returns true if the fifo is empty + * @fifo: address of the fifo to be used */ -static inline unsigned int __kfifo_off(struct kfifo *fifo, unsigned int off) -{ - return off & (fifo->size - 1); -} +#define kfifo_is_empty(fifo) \ +({ \ + typeof(fifo + 1) __tmpq = (fifo); \ + __tmpq->kfifo.in == __tmpq->kfifo.out; \ +}) -/* - * __kfifo_peek_n internal helper function for determinate the length of - * the next record in the fifo +/** + * kfifo_is_full - returns true if the fifo is full + * @fifo: address of the fifo to be used */ -static inline unsigned int __kfifo_peek_n(struct kfifo *fifo, - unsigned int recsize) -{ -#define __KFIFO_GET(fifo, off, shift) \ - ((fifo)->buffer[__kfifo_off((fifo), (fifo)->out+(off))] << (shift)) +#define kfifo_is_full(fifo) \ +({ \ + typeof(fifo + 1) __tmpq = (fifo); \ + kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ +}) - unsigned int l; +/** + * kfifo_avail - returns the number of unused elements in the fifo + * @fifo: address of the fifo to be used + */ +#define kfifo_avail(fifo) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmpq = (fifo); \ + const size_t __recsize = sizeof(*__tmpq->rectype); \ + unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ + (__recsize) ? ((__avail <= __recsize) ? 0 : \ + __kfifo_max_r(__avail - __recsize, __recsize)) : \ + __avail; \ +}) \ +) - l = __KFIFO_GET(fifo, 0, 0); +/** + * kfifo_skip - skip output data + * @fifo: address of the fifo to be used + */ +#define kfifo_skip(fifo) \ +(void)({ \ + typeof(fifo + 1) __tmp = (fifo); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (__recsize) \ + __kfifo_skip_r(__kfifo, __recsize); \ + else \ + __kfifo->out++; \ +}) - if (--recsize) - l |= __KFIFO_GET(fifo, 1, 8); +/** + * kfifo_peek_len - gets the size of the next fifo record + * @fifo: address of the fifo to be used + * + * This function returns the size of the next fifo record in number of bytes. + */ +#define kfifo_peek_len(fifo) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ + __kfifo_len_r(__kfifo, __recsize); \ +}) \ +) - return l; -#undef __KFIFO_GET -} +/** + * kfifo_alloc - dynamically allocates a new fifo buffer + * @fifo: pointer to the fifo + * @size: the number of elements in the fifo, this must be a power of 2 + * @gfp_mask: get_free_pages mask, passed to kmalloc() + * + * This macro dynamically allocates a new fifo buffer. + * + * The numer of elements will be rounded-up to a power of 2. + * The fifo will be release with kfifo_free(). + * Return 0 if no error, otherwise an error code. + */ +#define kfifo_alloc(fifo, size, gfp_mask) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + __is_kfifo_ptr(__tmp) ? \ + __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ + -EINVAL; \ +}) \ +) -/* - * __kfifo_poke_n internal helper function for storing the length of - * the next record into the fifo +/** + * kfifo_free - frees the fifo + * @fifo: the fifo to be freed */ -static inline void __kfifo_poke_n(struct kfifo *fifo, - unsigned int recsize, unsigned int n) -{ -#define __KFIFO_PUT(fifo, off, val, shift) \ - ( \ - (fifo)->buffer[__kfifo_off((fifo), (fifo)->in+(off))] = \ - (unsigned char)((val) >> (shift)) \ - ) +#define kfifo_free(fifo) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (__is_kfifo_ptr(__tmp)) \ + __kfifo_free(__kfifo); \ +}) - __KFIFO_PUT(fifo, 0, n, 0); +/** + * kfifo_init - initialize a fifo using a preallocated buffer + * @fifo: the fifo to assign the buffer + * @buffer: the preallocated buffer to be used + * @size: the size of the internal buffer, this have to be a power of 2 + * + * This macro initialize a fifo using a preallocated buffer. + * + * The numer of elements will be rounded-up to a power of 2. + * Return 0 if no error, otherwise an error code. + */ +#define kfifo_init(fifo, buffer, size) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + __is_kfifo_ptr(__tmp) ? \ + __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ + -EINVAL; \ +}) - if (--recsize) - __KFIFO_PUT(fifo, 1, n, 8); -#undef __KFIFO_PUT -} +/** + * kfifo_put - put data into the fifo + * @fifo: address of the fifo to be used + * @val: the data to be added + * + * This macro copies the given value into the fifo. + * It returns 0 if the fifo was full. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_put(fifo, val) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(val + 1) __val = (val); \ + unsigned int __ret; \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ + __dummy = (typeof(__val))NULL; \ + } \ + if (__recsize) \ + __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !kfifo_is_full(__tmp); \ + if (__ret) { \ + (__is_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__kfifo->data) : \ + (__tmp->buf) \ + )[__kfifo->in & __tmp->kfifo.mask] = \ + *(typeof(__tmp->type))__val; \ + smp_wmb(); \ + __kfifo->in++; \ + } \ + } \ + __ret; \ +}) -/* - * __kfifo_in_... internal functions for put date into the fifo - * do not call it directly, use kfifo_in_rec() instead - */ -extern unsigned int __kfifo_in_n(struct kfifo *fifo, - const void *from, unsigned int n, unsigned int recsize); +/** + * kfifo_get - get data from the fifo + * @fifo: address of the fifo to be used + * @val: the var where to store the data to be added + * + * This macro reads the data from the fifo. + * It returns 0 if the fifo was empty. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_get(fifo, val) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(val + 1) __val = (val); \ + unsigned int __ret; \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) \ + __val = (typeof(__tmp->ptr))0; \ + if (__recsize) \ + __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !kfifo_is_empty(__tmp); \ + if (__ret) { \ + *(typeof(__tmp->type))__val = \ + (__is_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__kfifo->data) : \ + (__tmp->buf) \ + )[__kfifo->out & __tmp->kfifo.mask]; \ + smp_wmb(); \ + __kfifo->out++; \ + } \ + } \ + __ret; \ +}) \ +) -extern unsigned int __kfifo_in_generic(struct kfifo *fifo, - const void *from, unsigned int n, unsigned int recsize); +/** + * kfifo_peek - get data from the fifo without removing + * @fifo: address of the fifo to be used + * @val: the var where to store the data to be added + * + * This reads the data from the fifo without removing it from the fifo. + * It returns 0 if the fifo was empty. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_peek(fifo, val) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(val + 1) __val = (val); \ + unsigned int __ret; \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) \ + __val = (typeof(__tmp->ptr))NULL; \ + if (__recsize) \ + __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !kfifo_is_empty(__tmp); \ + if (__ret) { \ + *(typeof(__tmp->type))__val = \ + (__is_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__kfifo->data) : \ + (__tmp->buf) \ + )[__kfifo->out & __tmp->kfifo.mask]; \ + smp_wmb(); \ + } \ + } \ + __ret; \ +}) \ +) -static inline unsigned int __kfifo_in_rec(struct kfifo *fifo, - const void *from, unsigned int n, unsigned int recsize) -{ - unsigned int ret; +/** + * kfifo_in - put data into the fifo + * @fifo: address of the fifo to be used + * @buf: the data to be added + * @n: number of elements to be added + * + * This macro copies the given buffer into the fifo and returns the + * number of copied elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_in(fifo, buf, n) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(buf + 1) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ + __dummy = (typeof(__buf))NULL; \ + } \ + (__recsize) ?\ + __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ + __kfifo_in(__kfifo, __buf, __n); \ +}) - ret = __kfifo_in_n(fifo, from, n, recsize); +/** + * kfifo_in_spinlocked - put data into the fifo using a spinlock for locking + * @fifo: address of the fifo to be used + * @buf: the data to be added + * @n: number of elements to be added + * @lock: pointer to the spinlock to use for locking + * + * This macro copies the given values buffer into the fifo and returns the + * number of copied elements. + */ +#define kfifo_in_spinlocked(fifo, buf, n, lock) \ +({ \ + unsigned long __flags; \ + unsigned int __ret; \ + spin_lock_irqsave(lock, __flags); \ + __ret = kfifo_in(fifo, buf, n); \ + spin_unlock_irqrestore(lock, __flags); \ + __ret; \ +}) + +/* alias for kfifo_in_spinlocked, will be removed in a future release */ +#define kfifo_in_locked(fifo, buf, n, lock) \ + kfifo_in_spinlocked(fifo, buf, n, lock) - if (likely(ret == 0)) { - if (recsize) - __kfifo_poke_n(fifo, recsize, n); - __kfifo_add_in(fifo, n + recsize); - } - return ret; -} +/** + * kfifo_out - get data from the fifo + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * + * This macro get some data from the fifo and return the numbers of elements + * copied. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_out(fifo, buf, n) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(buf + 1) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr) __dummy = NULL; \ + __buf = __dummy; \ + } \ + (__recsize) ?\ + __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ + __kfifo_out(__kfifo, __buf, __n); \ +}) \ +) + +/** + * kfifo_out_spinlocked - get data from the fifo using a spinlock for locking + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * @lock: pointer to the spinlock to use for locking + * + * This macro get the data from the fifo and return the numbers of elements + * copied. + */ +#define kfifo_out_spinlocked(fifo, buf, n, lock) \ +__kfifo_must_check_helper( \ +({ \ + unsigned long __flags; \ + unsigned int __ret; \ + spin_lock_irqsave(lock, __flags); \ + __ret = kfifo_out(fifo, buf, n); \ + spin_unlock_irqrestore(lock, __flags); \ + __ret; \ +}) \ +) + +/* alias for kfifo_out_spinlocked, will be removed in a future release */ +#define kfifo_out_locked(fifo, buf, n, lock) \ + kfifo_out_spinlocked(fifo, buf, n, lock) /** - * kfifo_in_rec - puts some record data into the FIFO - * @fifo: the fifo to be used. - * @from: the data to be added. - * @n: the length of the data to be added. - * @recsize: size of record field + * kfifo_from_user - puts some data from user space into the fifo + * @fifo: address of the fifo to be used + * @from: pointer to the data to be added + * @len: the length of the data to be added + * @copied: pointer to output variable to store the number of copied bytes * - * This function copies @n bytes from the @from into the FIFO and returns - * the number of bytes which cannot be copied. - * A returned value greater than the @n value means that the record doesn't - * fit into the buffer. + * This macro copies at most @len bytes from the @from into the + * fifo, depending of the available space and returns -EFAULT/0. * * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these functions. - */ -static inline __must_check unsigned int kfifo_in_rec(struct kfifo *fifo, - void *from, unsigned int n, unsigned int recsize) -{ - if (!__builtin_constant_p(recsize)) - return __kfifo_in_generic(fifo, from, n, recsize); - return __kfifo_in_rec(fifo, from, n, recsize); -} + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_from_user(fifo, from, len, copied) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + const void __user *__from = (from); \ + unsigned int __len = (len); \ + unsigned int *__copied = (copied); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (__recsize) ? \ + __kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \ + __kfifo_from_user(__kfifo, __from, __len, __copied); \ +}) \ +) -/* - * __kfifo_out_... internal functions for get date from the fifo - * do not call it directly, use kfifo_out_rec() instead - */ -extern unsigned int __kfifo_out_n(struct kfifo *fifo, - void *to, unsigned int reclen, unsigned int recsize); +/** + * kfifo_to_user - copies data from the fifo into user space + * @fifo: address of the fifo to be used + * @to: where the data must be copied + * @len: the size of the destination buffer + * @copied: pointer to output variable to store the number of copied bytes + * + * This macro copies at most @len bytes from the fifo into the + * @to buffer and returns -EFAULT/0. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_to_user(fifo, to, len, copied) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + void __user *__to = (to); \ + unsigned int __len = (len); \ + unsigned int *__copied = (copied); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (__recsize) ? \ + __kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \ + __kfifo_to_user(__kfifo, __to, __len, __copied); \ +}) \ +) + +/** + * kfifo_dma_in_prepare - setup a scatterlist for DMA input + * @fifo: address of the fifo to be used + * @sgl: pointer to the scatterlist array + * @nents: number of entries in the scatterlist array + * @len: number of elements to transfer + * + * This macro fills a scatterlist for DMA input. + * It returns the number entries in the scatterlist array. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macros. + */ +#define kfifo_dma_in_prepare(fifo, sgl, nents, len) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + struct scatterlist *__sgl = (sgl); \ + int __nents = (nents); \ + unsigned int __len = (len); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (__recsize) ? \ + __kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ + __kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \ +}) -extern unsigned int __kfifo_out_generic(struct kfifo *fifo, - void *to, unsigned int n, - unsigned int recsize, unsigned int *total); +/** + * kfifo_dma_in_finish - finish a DMA IN operation + * @fifo: address of the fifo to be used + * @len: number of bytes to received + * + * This macro finish a DMA IN operation. The in counter will be updated by + * the len parameter. No error checking will be done. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macros. + */ +#define kfifo_dma_in_finish(fifo, len) \ +(void)({ \ + typeof(fifo + 1) __tmp = (fifo); \ + unsigned int __len = (len); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (__recsize) \ + __kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \ + else \ + __kfifo->in += __len / sizeof(*__tmp->type); \ +}) -static inline unsigned int __kfifo_out_rec(struct kfifo *fifo, - void *to, unsigned int n, unsigned int recsize, - unsigned int *total) -{ - unsigned int l; - - if (!recsize) { - l = n; - if (total) - *total = l; - } else { - l = __kfifo_peek_n(fifo, recsize); - if (total) - *total = l; - if (n < l) - return l; - } +/** + * kfifo_dma_out_prepare - setup a scatterlist for DMA output + * @fifo: address of the fifo to be used + * @sgl: pointer to the scatterlist array + * @nents: number of entries in the scatterlist array + * @len: number of elements to transfer + * + * This macro fills a scatterlist for DMA output which at most @len bytes + * to transfer. + * It returns the number entries in the scatterlist array. + * A zero means there is no space available and the scatterlist is not filled. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macros. + */ +#define kfifo_dma_out_prepare(fifo, sgl, nents, len) \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + struct scatterlist *__sgl = (sgl); \ + int __nents = (nents); \ + unsigned int __len = (len); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (__recsize) ? \ + __kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ + __kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \ +}) - return __kfifo_out_n(fifo, to, l, recsize); -} +/** + * kfifo_dma_out_finish - finish a DMA OUT operation + * @fifo: address of the fifo to be used + * @len: number of bytes transferd + * + * This macro finish a DMA OUT operation. The out counter will be updated by + * the len parameter. No error checking will be done. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macros. + */ +#define kfifo_dma_out_finish(fifo, len) \ +(void)({ \ + typeof(fifo + 1) __tmp = (fifo); \ + unsigned int __len = (len); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (__recsize) \ + __kfifo_dma_out_finish_r(__kfifo, __recsize); \ + else \ + __kfifo->out += __len / sizeof(*__tmp->type); \ +}) /** - * kfifo_out_rec - gets some record data from the FIFO - * @fifo: the fifo to be used. - * @to: where the data must be copied. - * @n: the size of the destination buffer. - * @recsize: size of record field - * @total: pointer where the total number of to copied bytes should stored + * kfifo_out_peek - gets some data from the fifo + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get * - * This function copies at most @n bytes from the FIFO to @to and returns the - * number of bytes which cannot be copied. - * A returned value greater than the @n value means that the record doesn't - * fit into the @to buffer. + * This macro get the data from the fifo and return the numbers of elements + * copied. The data is not removed from the fifo. * * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these functions. + * writer, you don't need extra locking to use these macro. */ -static inline __must_check unsigned int kfifo_out_rec(struct kfifo *fifo, - void *to, unsigned int n, unsigned int recsize, - unsigned int *total) +#define kfifo_out_peek(fifo, buf, n) \ +__kfifo_must_check_helper( \ +({ \ + typeof(fifo + 1) __tmp = (fifo); \ + typeof(buf + 1) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ + __buf = __dummy; \ + } \ + (__recsize) ? \ + __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ + __kfifo_out_peek(__kfifo, __buf, __n); \ +}) \ +) -{ - if (!__builtin_constant_p(recsize)) - return __kfifo_out_generic(fifo, to, n, recsize, total); - return __kfifo_out_rec(fifo, to, n, recsize, total); -} +extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, + size_t esize, gfp_t gfp_mask); -/* - * __kfifo_from_user_... internal functions for transfer from user space into - * the fifo. do not call it directly, use kfifo_from_user_rec() instead - */ -extern unsigned int __kfifo_from_user_n(struct kfifo *fifo, - const void __user *from, unsigned int n, unsigned int recsize); +extern void __kfifo_free(struct __kfifo *fifo); -extern unsigned int __kfifo_from_user_generic(struct kfifo *fifo, - const void __user *from, unsigned int n, unsigned int recsize); +extern int __kfifo_init(struct __kfifo *fifo, void *buffer, + unsigned int size, size_t esize); -static inline unsigned int __kfifo_from_user_rec(struct kfifo *fifo, - const void __user *from, unsigned int n, unsigned int recsize) -{ - unsigned int ret; +extern unsigned int __kfifo_in(struct __kfifo *fifo, + const void *buf, unsigned int len); - ret = __kfifo_from_user_n(fifo, from, n, recsize); +extern unsigned int __kfifo_out(struct __kfifo *fifo, + void *buf, unsigned int len); - if (likely(ret == 0)) { - if (recsize) - __kfifo_poke_n(fifo, recsize, n); - __kfifo_add_in(fifo, n + recsize); - } - return ret; -} +extern int __kfifo_from_user(struct __kfifo *fifo, + const void __user *from, unsigned long len, unsigned int *copied); -/** - * kfifo_from_user_rec - puts some data from user space into the FIFO - * @fifo: the fifo to be used. - * @from: pointer to the data to be added. - * @n: the length of the data to be added. - * @recsize: size of record field - * - * This function copies @n bytes from the @from into the - * FIFO and returns the number of bytes which cannot be copied. - * - * If the returned value is equal or less the @n value, the copy_from_user() - * functions has failed. Otherwise the record doesn't fit into the buffer. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these functions. - */ -static inline __must_check unsigned int kfifo_from_user_rec(struct kfifo *fifo, - const void __user *from, unsigned int n, unsigned int recsize) -{ - if (!__builtin_constant_p(recsize)) - return __kfifo_from_user_generic(fifo, from, n, recsize); - return __kfifo_from_user_rec(fifo, from, n, recsize); -} +extern int __kfifo_to_user(struct __kfifo *fifo, + void __user *to, unsigned long len, unsigned int *copied); -/* - * __kfifo_to_user_... internal functions for transfer fifo data into user space - * do not call it directly, use kfifo_to_user_rec() instead - */ -extern unsigned int __kfifo_to_user_n(struct kfifo *fifo, - void __user *to, unsigned int n, unsigned int reclen, - unsigned int recsize); +extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo, + struct scatterlist *sgl, int nents, unsigned int len); -extern unsigned int __kfifo_to_user_generic(struct kfifo *fifo, - void __user *to, unsigned int n, unsigned int recsize, - unsigned int *total); +extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo, + struct scatterlist *sgl, int nents, unsigned int len); -static inline unsigned int __kfifo_to_user_rec(struct kfifo *fifo, - void __user *to, unsigned int n, - unsigned int recsize, unsigned int *total) -{ - unsigned int l; - - if (!recsize) { - l = n; - if (total) - *total = l; - } else { - l = __kfifo_peek_n(fifo, recsize); - if (total) - *total = l; - if (n < l) - return l; - } +extern unsigned int __kfifo_out_peek(struct __kfifo *fifo, + void *buf, unsigned int len); - return __kfifo_to_user_n(fifo, to, n, l, recsize); -} +extern unsigned int __kfifo_in_r(struct __kfifo *fifo, + const void *buf, unsigned int len, size_t recsize); -/** - * kfifo_to_user_rec - gets data from the FIFO and write it to user space - * @fifo: the fifo to be used. - * @to: where the data must be copied. - * @n: the size of the destination buffer. - * @recsize: size of record field - * @total: pointer where the total number of to copied bytes should stored - * - * This function copies at most @n bytes from the FIFO to the @to. - * In case of an error, the function returns the number of bytes which cannot - * be copied. - * If the returned value is equal or less the @n value, the copy_to_user() - * functions has failed. Otherwise the record doesn't fit into the @to buffer. - * - * Note that with only one concurrent reader and one concurrent - * writer, you don't need extra locking to use these functions. - */ -static inline __must_check unsigned int kfifo_to_user_rec(struct kfifo *fifo, - void __user *to, unsigned int n, unsigned int recsize, - unsigned int *total) -{ - if (!__builtin_constant_p(recsize)) - return __kfifo_to_user_generic(fifo, to, n, recsize, total); - return __kfifo_to_user_rec(fifo, to, n, recsize, total); -} +extern unsigned int __kfifo_out_r(struct __kfifo *fifo, + void *buf, unsigned int len, size_t recsize); -/* - * __kfifo_peek_... internal functions for peek into the next fifo record - * do not call it directly, use kfifo_peek_rec() instead - */ -extern unsigned int __kfifo_peek_generic(struct kfifo *fifo, - unsigned int recsize); +extern int __kfifo_from_user_r(struct __kfifo *fifo, + const void __user *from, unsigned long len, unsigned int *copied, + size_t recsize); -/** - * kfifo_peek_rec - gets the size of the next FIFO record data - * @fifo: the fifo to be used. - * @recsize: size of record field - * - * This function returns the size of the next FIFO record in number of bytes - */ -static inline __must_check unsigned int kfifo_peek_rec(struct kfifo *fifo, - unsigned int recsize) -{ - if (!__builtin_constant_p(recsize)) - return __kfifo_peek_generic(fifo, recsize); - if (!recsize) - return kfifo_len(fifo); - return __kfifo_peek_n(fifo, recsize); -} +extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to, + unsigned long len, unsigned int *copied, size_t recsize); -/* - * __kfifo_skip_... internal functions for skip the next fifo record - * do not call it directly, use kfifo_skip_rec() instead - */ -extern void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize); +extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo, + struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); -static inline void __kfifo_skip_rec(struct kfifo *fifo, - unsigned int recsize) -{ - unsigned int l; +extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo, + unsigned int len, size_t recsize); - if (recsize) { - l = __kfifo_peek_n(fifo, recsize); +extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo, + struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); - if (l + recsize <= kfifo_len(fifo)) { - __kfifo_add_out(fifo, l + recsize); - return; - } - } - kfifo_reset_out(fifo); -} +extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize); -/** - * kfifo_skip_rec - skip the next fifo out record - * @fifo: the fifo to be used. - * @recsize: size of record field - * - * This function skips the next FIFO record - */ -static inline void kfifo_skip_rec(struct kfifo *fifo, - unsigned int recsize) -{ - if (!__builtin_constant_p(recsize)) - __kfifo_skip_generic(fifo, recsize); - else - __kfifo_skip_rec(fifo, recsize); -} +extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize); -/** - * kfifo_avail_rec - returns the number of bytes available in a record FIFO - * @fifo: the fifo to be used. - * @recsize: size of record field - */ -static inline __must_check unsigned int kfifo_avail_rec(struct kfifo *fifo, - unsigned int recsize) -{ - unsigned int l = kfifo_size(fifo) - kfifo_len(fifo); +extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, + void *buf, unsigned int len, size_t recsize); - return (l > recsize) ? l - recsize : 0; -} +extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize); #endif -- cgit v1.1 From 9a94241afcc9a481691a9c29b7460217925b59b8 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 11 Aug 2010 18:20:56 +0200 Subject: i2c: Add support for custom probe function The probe method used by i2c_new_probed_device() may not be suitable for all cases. Let the caller provide its own, optional probe function. Signed-off-by: Jean Delvare Acked-by: Mauro Carvalho Chehab --- include/linux/i2c.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 38dd402..59a9f3c 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -284,12 +284,15 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info); /* If you don't know the exact address of an I2C device, use this variant * instead, which can probe for device presence in a list of possible - * addresses. + * addresses. The "probe" callback function is optional. If it is provided, + * it must return 1 on successful probe, 0 otherwise. If it is not provided, + * a default probing method is used. */ extern struct i2c_client * i2c_new_probed_device(struct i2c_adapter *adap, struct i2c_board_info *info, - unsigned short const *addr_list); + unsigned short const *addr_list, + int (*probe)(struct i2c_adapter *, unsigned short addr)); /* For devices that use several addresses, use i2c_new_dummy() to make * client handles for the extra addresses. -- cgit v1.1 From d44f19d586b6113fb5db10e1a36457f0db3b01aa Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 11 Aug 2010 18:20:57 +0200 Subject: V4L/DVB: Use custom I2C probing function mechanism Now that i2c-core offers the possibility to provide custom probing function for I2C devices, let's make use of it. Signed-off-by: Jean Delvare Acked-by: Mauro Carvalho Chehab --- include/linux/i2c.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 59a9f3c..c8627e4 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -294,6 +294,9 @@ i2c_new_probed_device(struct i2c_adapter *adap, unsigned short const *addr_list, int (*probe)(struct i2c_adapter *, unsigned short addr)); +/* Common custom probe functions */ +extern int i2c_probe_func_quick_read(struct i2c_adapter *, unsigned short addr); + /* For devices that use several addresses, use i2c_new_dummy() to make * client handles for the extra addresses. */ -- cgit v1.1 From fe61e07e9ebc890c70d97a1f72ddaad4bee2d848 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 11 Aug 2010 18:20:58 +0200 Subject: i2c: Move adapter locking helpers to i2c-core Uninline i2c adapter locking helper functions, move them to i2c-core, and use them in i2c-core itself. The functions are still exported for external users. This makes future updates to the locking model (which will be needed for multiplexing support) possible and transparent. Signed-off-by: Jean Delvare Cc: Michael Lawnick --- include/linux/i2c.h | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index c8627e4..5bf0f4b 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -382,23 +382,9 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data) dev_set_drvdata(&dev->dev, data); } -/** - * i2c_lock_adapter - Prevent access to an I2C bus segment - * @adapter: Target I2C bus segment - */ -static inline void i2c_lock_adapter(struct i2c_adapter *adapter) -{ - rt_mutex_lock(&adapter->bus_lock); -} - -/** - * i2c_unlock_adapter - Reauthorize access to an I2C bus segment - * @adapter: Target I2C bus segment - */ -static inline void i2c_unlock_adapter(struct i2c_adapter *adapter) -{ - rt_mutex_unlock(&adapter->bus_lock); -} +/* Adapter locking functions, exported for shared pin cases */ +void i2c_lock_adapter(struct i2c_adapter *); +void i2c_unlock_adapter(struct i2c_adapter *); /*flags for the client struct: */ #define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ -- cgit v1.1 From dafc50d141c27959dbd3a1cfe9857a86d23402a7 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 11 Aug 2010 18:21:01 +0200 Subject: i2c: Use a separate mutex for userspace client lists Moving userspace-instantiated clients to separate lists wasn't nearly enough to avoid deadlocks in multiplexed bus cases. We also want to have a dedicated mutex to protect each list. Signed-off-by: Jean Delvare Cc: Michael Lawnick --- include/linux/i2c.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 5bf0f4b..798bad8 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -368,6 +368,7 @@ struct i2c_adapter { char name[48]; struct completion dev_released; + struct mutex userspace_clients_lock; struct list_head userspace_clients; }; #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) -- cgit v1.1 From 0826374bff57411d239f2fcb15da3c35af0a93cd Mon Sep 17 00:00:00 2001 From: Michael Lawnick Date: Wed, 11 Aug 2010 18:21:02 +0200 Subject: i2c: Multiplexed I2C bus core support Add multiplexed bus core support. I2C multiplexer and switches like pca954x get instantiated as new adapters per port. Signed-off-by: Michael Lawnick Acked-by: Rodolfo Giometti Signed-off-by: Jean Delvare --- include/linux/i2c-mux.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/i2c.h | 8 ++++++++ 2 files changed, 54 insertions(+) create mode 100644 include/linux/i2c-mux.h (limited to 'include') diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h new file mode 100644 index 0000000..34536ef --- /dev/null +++ b/include/linux/i2c-mux.h @@ -0,0 +1,46 @@ +/* + * + * i2c-mux.h - functions for the i2c-bus mux support + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * Michael Lawnick + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _LINUX_I2C_MUX_H +#define _LINUX_I2C_MUX_H + +#ifdef __KERNEL__ + +/* + * Called to create a i2c bus on a multiplexed bus segment. + * The mux_dev and chan_id parameters are passed to the select + * and deselect callback functions to perform hardware-specific + * mux control. + */ +struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, + void *mux_dev, u32 force_nr, u32 chan_id, + int (*select) (struct i2c_adapter *, + void *mux_dev, u32 chan_id), + int (*deselect) (struct i2c_adapter *, + void *mux_dev, u32 chan_id)); + +int i2c_del_mux_adapter(struct i2c_adapter *adap); + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_I2C_MUX_H */ diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 798bad8..4bae0b7 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -37,6 +37,7 @@ #include /* for struct device_node */ extern struct bus_type i2c_bus_type; +extern struct device_type i2c_adapter_type; /* --- General options ------------------------------------------------ */ @@ -383,6 +384,13 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data) dev_set_drvdata(&dev->dev, data); } +static inline int i2c_parent_is_i2c_adapter(const struct i2c_adapter *adapter) +{ + return adapter->dev.parent != NULL + && adapter->dev.parent->bus == &i2c_bus_type + && adapter->dev.parent->type == &i2c_adapter_type; +} + /* Adapter locking functions, exported for shared pin cases */ void i2c_lock_adapter(struct i2c_adapter *); void i2c_unlock_adapter(struct i2c_adapter *); -- cgit v1.1 From 7f528135da9704d67db1f727162024b078e1cd8f Mon Sep 17 00:00:00 2001 From: Michael Lawnick Date: Wed, 11 Aug 2010 18:21:03 +0200 Subject: i2c: I2C bus multiplexer driver pca954x I2C driver for PCA954x I2C multiplexer series. Signed-off-by: Michael Lawnick Acked-by: Rodolfo Giometti Signed-off-by: Jean Delvare --- include/linux/i2c/pca954x.h | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 include/linux/i2c/pca954x.h (limited to 'include') diff --git a/include/linux/i2c/pca954x.h b/include/linux/i2c/pca954x.h new file mode 100644 index 0000000..28f1f8d --- /dev/null +++ b/include/linux/i2c/pca954x.h @@ -0,0 +1,47 @@ +/* + * + * pca954x.h - I2C multiplexer/switch support + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * Michael Lawnick + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef _LINUX_I2C_PCA954X_H +#define _LINUX_I2C_PCA954X_H + +/* Platform data for the PCA954x I2C multiplexers */ + +/* Per channel initialisation data: + * @adap_id: bus number for the adapter. 0 = don't care + * @deselect_on_exit: set this entry to 1, if your H/W needs deselection + * of this channel after transaction. + * + */ +struct pca954x_platform_mode { + int adap_id; + unsigned int deselect_on_exit:1; +}; + +/* Per mux/switch data, used with i2c_register_board_info */ +struct pca954x_platform_data { + struct pca954x_platform_mode *modes; + int num_modes; +}; + +#endif /* _LINUX_I2C_PCA954X_H */ -- cgit v1.1 From d5302fe41ffb28d0a48be6a71becba36d3453ae0 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 12 Aug 2010 06:38:24 +1000 Subject: Make lib/raid6/test build correctly. Some bit-rot needs to be cleaned out. Signed-off-by: NeilBrown --- include/linux/raid/pq.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/raid/pq.h b/include/linux/raid/pq.h index 1cbbd2c..2b59cc8 100644 --- a/include/linux/raid/pq.h +++ b/include/linux/raid/pq.h @@ -62,7 +62,9 @@ extern const char raid6_empty_zero_page[PAGE_SIZE]; #define disable_kernel_altivec() #define EXPORT_SYMBOL(sym) +#define EXPORT_SYMBOL_GPL(sym) #define MODULE_LICENSE(licence) +#define MODULE_DESCRIPTION(desc) #define subsys_initcall(x) #define module_exit(x) #endif /* __KERNEL__ */ -- cgit v1.1 From 71beefe8c0b9e12ed4ac9fe13b98a035ddeaf8eb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 12 Aug 2010 11:44:50 +1000 Subject: vgaarb: drop vga.h include We don't actually need this include on any platform. built on powerpc + x86, reported on m68k. Reported-by: Geert Uytterhoeven Signed-off-by: Dave Airlie --- include/linux/vgaarb.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h index 814f294..6228b5b 100644 --- a/include/linux/vgaarb.h +++ b/include/linux/vgaarb.h @@ -31,7 +31,6 @@ #ifndef LINUX_VGA_H #define LINUX_VGA_H -#include /* Legacy VGA regions */ #define VGA_RSRC_NONE 0x00 -- cgit v1.1 From 31ce4bfdfd10bf5db9bf85c92bbe0cf2edbdcad8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 12 Aug 2010 11:47:50 +1000 Subject: io-mapping: move asm include inside the config option nouveau starting using these APIs, the first on non-x86 hw, and this include isn't required on anything with real amounts of vmalloc space. this fixes a build problem on powerpc. Signed-off-by: Dave Airlie --- include/linux/io-mapping.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index e0ea40f..0a6b3d5 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h @@ -22,7 +22,6 @@ #include #include #include -#include /* * The io_mapping mechanism provides an abstraction for mapping @@ -33,6 +32,8 @@ #ifdef CONFIG_HAVE_ATOMIC_IOMAP +#include + struct io_mapping { resource_size_t base; unsigned long size; -- cgit v1.1 From a5664dad7e1a278d2915c2bf79cf42250e12d7db Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 12 Aug 2010 04:14:01 +0100 Subject: dm ioctl: make bio or request based device type immutable Determine whether a mapped device is bio-based or request-based when loading its first (inactive) table and don't allow that to be changed later. This patch performs different device initialisation in each of the two cases. (We don't think it's necessary to add code to support changing between the two types.) Allowed md->type transitions: DM_TYPE_NONE to DM_TYPE_BIO_BASED DM_TYPE_NONE to DM_TYPE_REQUEST_BASED We now prevent table_load from replacing the inactive table with a conflicting type of table even after an explicit table_clear. Introduce 'type_lock' into the struct mapped_device to protect md->type and to prepare for the next patch that will change the queue initialization and allocate memory while md->type_lock is held. Signed-off-by: Mike Snitzer Acked-by: Kiyoshi Ueda Signed-off-by: Alasdair G Kergon drivers/md/dm-ioctl.c | 15 +++++++++++++++ drivers/md/dm.c | 37 ++++++++++++++++++++++++++++++------- drivers/md/dm.h | 5 +++++ include/linux/dm-ioctl.h | 4 ++-- 4 files changed, 52 insertions(+), 9 deletions(-) --- include/linux/dm-ioctl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h index 2c445e1..43b2de1 100644 --- a/include/linux/dm-ioctl.h +++ b/include/linux/dm-ioctl.h @@ -266,9 +266,9 @@ enum { #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) #define DM_VERSION_MAJOR 4 -#define DM_VERSION_MINOR 17 +#define DM_VERSION_MINOR 18 #define DM_VERSION_PATCHLEVEL 0 -#define DM_VERSION_EXTRA "-ioctl (2010-03-05)" +#define DM_VERSION_EXTRA "-ioctl (2010-06-29)" /* Status bits */ #define DM_READONLY_FLAG (1 << 0) /* In/Out */ -- cgit v1.1 From 57cba5d3658d9fdc019c6af14a2d80aefa651e56 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 12 Aug 2010 04:14:04 +0100 Subject: dm: rename map_info flush_request to target_request_nr 'target_request_nr' is a more generic name that reflects the fact that it will be used for both flush and discard support. Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon --- include/linux/device-mapper.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 1381cd9..531a6f2 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -22,7 +22,7 @@ typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE } status_type_t; union map_info { void *ptr; unsigned long long ll; - unsigned flush_request; + unsigned target_request_nr; }; /* @@ -174,7 +174,7 @@ struct dm_target { * A number of zero-length barrier requests that will be submitted * to the target for the purpose of flushing cache. * - * The request number will be placed in union map_info->flush_request. + * The request number will be placed in union map_info->target_request_nr. * It is a responsibility of the target driver to remap these requests * to the real underlying devices. */ -- cgit v1.1 From 7e507eb6432afdd798d4c6dccf949b8c43ef151c Mon Sep 17 00:00:00 2001 From: Peter Rajnoha Date: Thu, 12 Aug 2010 04:14:05 +0100 Subject: dm: allow autoloading of dm mod Add devname:mapper/control and MAPPER_CTRL_MINOR module alias to support dm-mod module autoloading. Signed-off-by: Kay Sievers Signed-off-by: Peter Rajnoha Signed-off-by: Alasdair G Kergon --- include/linux/dm-ioctl.h | 1 + include/linux/miscdevice.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h index 43b2de1..49eab36 100644 --- a/include/linux/dm-ioctl.h +++ b/include/linux/dm-ioctl.h @@ -11,6 +11,7 @@ #include #define DM_DIR "mapper" /* Slashes not supported */ +#define DM_CONTROL_NODE "control" #define DM_MAX_TYPE_NAME 16 #define DM_NAME_LEN 128 #define DM_UUID_LEN 129 diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index f6c9b7d..bafffc7 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -38,6 +38,7 @@ #define KVM_MINOR 232 #define BTRFS_MINOR 234 #define AUTOFS_MINOR 235 +#define MAPPER_CTRL_MINOR 236 #define MISC_DYNAMIC_MINOR 255 struct device; -- cgit v1.1 From 5ae89a8720c28caf35c4e53711d77df2856c404e Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 12 Aug 2010 04:14:08 +0100 Subject: dm: linear support discard Allow discards to be passed through to linear mappings if at least one underlying device supports it. Discards will be forwarded only to devices that support them. A target that supports discards should set num_discard_requests to indicate how many times each discard request must be submitted to it. Verify table's underlying devices support discards prior to setting the associated DM device as capable of discards (via QUEUE_FLAG_DISCARD). Signed-off-by: Mike Snitzer Signed-off-by: Mikulas Patocka Reviewed-by: Joe Thornber Signed-off-by: Alasdair G Kergon --- include/linux/device-mapper.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 531a6f2..751ce21 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -180,6 +180,12 @@ struct dm_target { */ unsigned num_flush_requests; + /* + * The number of discard requests that will be submitted to the + * target. map_info->request_nr is used just like num_flush_requests. + */ + unsigned num_discard_requests; + /* target specific data */ void *private; -- cgit v1.1 From 56a67df766039666f61fb15b079f713e44a735ae Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 12 Aug 2010 04:14:10 +0100 Subject: dm: factor out max_io_len_target_boundary Split max_io_len_target_boundary out of max_io_len so that the discard support can make use of it without duplicating max_io_len code. Avoiding max_io_len's split_io logic enables DM's discard support to submit the entire discard request to a target. But discards must still be split on target boundaries. Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon --- include/linux/device-mapper.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 751ce21..2970022 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -398,6 +398,12 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size); #define dm_array_too_big(fixed, obj, num) \ ((num) > (UINT_MAX - (fixed)) / (obj)) +/* + * Sector offset taken relative to the start of the target instead of + * relative to the start of the device. + */ +#define dm_target_offset(ti, sector) ((sector) - (ti)->begin) + static inline sector_t to_sector(unsigned long n) { return (n >> SECTOR_SHIFT); -- cgit v1.1 From 27e34995e1a863c1e9beba30e51dfe2a083f918d Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Fri, 2 Jul 2010 16:52:08 +0530 Subject: mfd: Add STMPE I/O Expander support Add support for the STMPE family of I/O Expanders from STMicroelectronics. These devices include upto 24 gpios and a varying selection of blocks, including PWM, keypad, and touchscreen controllers. This patch adds the MFD core. [l.fu@pengutronix.de: fix stmpe811 enable hook] [l.fu@pengutronix.de: add touchscreen platform data] Acked-by: Luotao Fu Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Samuel Ortiz --- include/linux/mfd/stmpe.h | 197 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 include/linux/mfd/stmpe.h (limited to 'include') diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h new file mode 100644 index 0000000..90faa98 --- /dev/null +++ b/include/linux/mfd/stmpe.h @@ -0,0 +1,197 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License, version 2 + * Author: Rabin Vincent for ST-Ericsson + */ + +#ifndef __LINUX_MFD_STMPE_H +#define __LINUX_MFD_STMPE_H + +#include + +enum stmpe_block { + STMPE_BLOCK_GPIO = 1 << 0, + STMPE_BLOCK_KEYPAD = 1 << 1, + STMPE_BLOCK_TOUCHSCREEN = 1 << 2, + STMPE_BLOCK_ADC = 1 << 3, + STMPE_BLOCK_PWM = 1 << 4, + STMPE_BLOCK_ROTATOR = 1 << 5, +}; + +enum stmpe_partnum { + STMPE811, + STMPE1601, + STMPE2401, + STMPE2403, +}; + +/* + * For registers whose locations differ on variants, the correct address is + * obtained by indexing stmpe->regs with one of the following. + */ +enum { + STMPE_IDX_CHIP_ID, + STMPE_IDX_ICR_LSB, + STMPE_IDX_IER_LSB, + STMPE_IDX_ISR_MSB, + STMPE_IDX_GPMR_LSB, + STMPE_IDX_GPSR_LSB, + STMPE_IDX_GPCR_LSB, + STMPE_IDX_GPDR_LSB, + STMPE_IDX_GPEDR_MSB, + STMPE_IDX_GPRER_LSB, + STMPE_IDX_GPFER_LSB, + STMPE_IDX_GPAFR_U_MSB, + STMPE_IDX_IEGPIOR_LSB, + STMPE_IDX_ISGPIOR_MSB, + STMPE_IDX_MAX, +}; + + +struct stmpe_variant_info; + +/** + * struct stmpe - STMPE MFD structure + * @lock: lock protecting I/O operations + * @irq_lock: IRQ bus lock + * @dev: device, mostly for dev_dbg() + * @i2c: i2c client + * @variant: the detected STMPE model number + * @regs: list of addresses of registers which are at different addresses on + * different variants. Indexed by one of STMPE_IDX_*. + * @irq_base: starting IRQ number for internal IRQs + * @num_gpios: number of gpios, differs for variants + * @ier: cache of IER registers for bus_lock + * @oldier: cache of IER registers for bus_lock + * @pdata: platform data + */ +struct stmpe { + struct mutex lock; + struct mutex irq_lock; + struct device *dev; + struct i2c_client *i2c; + enum stmpe_partnum partnum; + struct stmpe_variant_info *variant; + const u8 *regs; + + int irq_base; + int num_gpios; + u8 ier[2]; + u8 oldier[2]; + struct stmpe_platform_data *pdata; +}; + +extern int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 data); +extern int stmpe_reg_read(struct stmpe *stmpe, u8 reg); +extern int stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, + u8 *values); +extern int stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length, + const u8 *values); +extern int stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val); +extern int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, + enum stmpe_block block); +extern int stmpe_enable(struct stmpe *stmpe, unsigned int blocks); +extern int stmpe_disable(struct stmpe *stmpe, unsigned int blocks); + +struct matrix_keymap_data; + +/** + * struct stmpe_keypad_platform_data - STMPE keypad platform data + * @keymap_data: key map table and size + * @debounce_ms: debounce interval, in ms. Maximum is + * %STMPE_KEYPAD_MAX_DEBOUNCE. + * @scan_count: number of key scanning cycles to confirm key data. + * Maximum is %STMPE_KEYPAD_MAX_SCAN_COUNT. + * @no_autorepeat: disable key autorepeat + */ +struct stmpe_keypad_platform_data { + struct matrix_keymap_data *keymap_data; + unsigned int debounce_ms; + unsigned int scan_count; + bool no_autorepeat; +}; + +/** + * struct stmpe_gpio_platform_data - STMPE GPIO platform data + * @gpio_base: first gpio number assigned. A maximum of + * %STMPE_NR_GPIOS GPIOs will be allocated. + */ +struct stmpe_gpio_platform_data { + int gpio_base; + void (*setup)(struct stmpe *stmpe, unsigned gpio_base); + void (*remove)(struct stmpe *stmpe, unsigned gpio_base); +}; + +/** + * struct stmpe_ts_platform_data - stmpe811 touch screen controller platform + * data + * @sample_time: ADC converstion time in number of clock. + * (0 -> 36 clocks, 1 -> 44 clocks, 2 -> 56 clocks, 3 -> 64 clocks, + * 4 -> 80 clocks, 5 -> 96 clocks, 6 -> 144 clocks), + * recommended is 4. + * @mod_12b: ADC Bit mode (0 -> 10bit ADC, 1 -> 12bit ADC) + * @ref_sel: ADC reference source + * (0 -> internal reference, 1 -> external reference) + * @adc_freq: ADC Clock speed + * (0 -> 1.625 MHz, 1 -> 3.25 MHz, 2 || 3 -> 6.5 MHz) + * @ave_ctrl: Sample average control + * (0 -> 1 sample, 1 -> 2 samples, 2 -> 4 samples, 3 -> 8 samples) + * @touch_det_delay: Touch detect interrupt delay + * (0 -> 10 us, 1 -> 50 us, 2 -> 100 us, 3 -> 500 us, + * 4-> 1 ms, 5 -> 5 ms, 6 -> 10 ms, 7 -> 50 ms) + * recommended is 3 + * @settling: Panel driver settling time + * (0 -> 10 us, 1 -> 100 us, 2 -> 500 us, 3 -> 1 ms, + * 4 -> 5 ms, 5 -> 10 ms, 6 for 50 ms, 7 -> 100 ms) + * recommended is 2 + * @fraction_z: Length of the fractional part in z + * (fraction_z ([0..7]) = Count of the fractional part) + * recommended is 7 + * @i_drive: current limit value of the touchscreen drivers + * (0 -> 20 mA typical 35 mA max, 1 -> 50 mA typical 80 mA max) + * + * */ +struct stmpe_ts_platform_data { + u8 sample_time; + u8 mod_12b; + u8 ref_sel; + u8 adc_freq; + u8 ave_ctrl; + u8 touch_det_delay; + u8 settling; + u8 fraction_z; + u8 i_drive; +}; + +/** + * struct stmpe_platform_data - STMPE platform data + * @id: device id to distinguish between multiple STMPEs on the same board + * @blocks: bitmask of blocks to enable (use STMPE_BLOCK_*) + * @irq_trigger: IRQ trigger to use for the interrupt to the host + * @irq_invert_polarity: IRQ line is connected with reversed polarity + * @irq_base: base IRQ number. %STMPE_NR_IRQS irqs will be used, or + * %STMPE_NR_INTERNAL_IRQS if the GPIO driver is not used. + * @gpio: GPIO-specific platform data + * @keypad: keypad-specific platform data + * @ts: touchscreen-specific platform data + */ +struct stmpe_platform_data { + int id; + unsigned int blocks; + int irq_base; + unsigned int irq_trigger; + bool irq_invert_polarity; + + struct stmpe_gpio_platform_data *gpio; + struct stmpe_keypad_platform_data *keypad; + struct stmpe_ts_platform_data *ts; +}; + +#define STMPE_NR_INTERNAL_IRQS 9 +#define STMPE_INT_GPIO(x) (STMPE_NR_INTERNAL_IRQS + (x)) + +#define STMPE_NR_GPIOS 24 +#define STMPE_NR_IRQS STMPE_INT_GPIO(STMPE_NR_GPIOS) + +#endif -- cgit v1.1 From 91f4debf5e2df904e7fade530bd1a6d182efd72c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 12 Jul 2010 03:48:08 +0200 Subject: mfd: Add JZ4740 ADC driver This patch adds a MFD driver for the JZ4740 ADC unit. The driver is used to demultiplex IRQs and synchronize access to shared registers between the battery, hwmon and (future) touchscreen driver. Signed-off-by: Lars-Peter Clausen Signed-off-by: Samuel Ortiz --- include/linux/jz4740-adc.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 include/linux/jz4740-adc.h (limited to 'include') diff --git a/include/linux/jz4740-adc.h b/include/linux/jz4740-adc.h new file mode 100644 index 0000000..9053f95 --- /dev/null +++ b/include/linux/jz4740-adc.h @@ -0,0 +1,32 @@ + +#ifndef __LINUX_JZ4740_ADC +#define __LINUX_JZ4740_ADC + +#include + +/* + * jz4740_adc_set_config - Configure a JZ4740 adc device + * @dev: Pointer to a jz4740-adc device + * @mask: Mask for the config value to be set + * @val: Value to be set + * + * This function can be used by the JZ4740 ADC mfd cells to configure their + * options in the shared config register. +*/ +int jz4740_adc_set_config(struct device *dev, uint32_t mask, uint32_t val); + +#define JZ_ADC_CONFIG_SPZZ BIT(31) +#define JZ_ADC_CONFIG_EX_IN BIT(30) +#define JZ_ADC_CONFIG_DNUM_MASK (0x7 << 16) +#define JZ_ADC_CONFIG_DMA_ENABLE BIT(15) +#define JZ_ADC_CONFIG_XYZ_MASK (0x2 << 13) +#define JZ_ADC_CONFIG_SAMPLE_NUM_MASK (0x7 << 10) +#define JZ_ADC_CONFIG_CLKDIV_MASK (0xf << 5) +#define JZ_ADC_CONFIG_BAT_MB BIT(4) + +#define JZ_ADC_CONFIG_DNUM(dnum) ((dnum) << 16) +#define JZ_ADC_CONFIG_XYZ_OFFSET(dnum) ((xyz) << 13) +#define JZ_ADC_CONFIG_SAMPLE_NUM(x) ((x) << 10) +#define JZ_ADC_CONFIG_CLKDIV(div) ((div) << 5) + +#endif -- cgit v1.1 From 9accdc1bf239ef20c0fe12ceff2a7532374fd7cd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 8 Jul 2010 21:09:51 +0900 Subject: mfd: Add additional WM8994 GPIO functions Later revisions of the WM8994 add some more GPIO functions, define them in the header file. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- include/linux/mfd/wm8994/gpio.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/mfd/wm8994/gpio.h b/include/linux/mfd/wm8994/gpio.h index b4d4c22..0c79b5f 100644 --- a/include/linux/mfd/wm8994/gpio.h +++ b/include/linux/mfd/wm8994/gpio.h @@ -36,6 +36,10 @@ #define WM8994_GP_FN_WSEQ_STATUS 16 #define WM8994_GP_FN_FIFO_ERROR 17 #define WM8994_GP_FN_OPCLK 18 +#define WM8994_GP_FN_THW 19 +#define WM8994_GP_FN_DCS_DONE 20 +#define WM8994_GP_FN_FLL1_OUT 21 +#define WM8994_GP_FN_FLL2_OUT 22 #define WM8994_GPN_DIR 0x8000 /* GPN_DIR */ #define WM8994_GPN_DIR_MASK 0x8000 /* GPN_DIR */ -- cgit v1.1 From 5981f4e65cb455a820b3d07b8e4bac506233f3ea Mon Sep 17 00:00:00 2001 From: Sundar R Iyer Date: Wed, 21 Jul 2010 11:41:07 +0530 Subject: mfd: Add stmpe auto sleep feature Some STMPE devices support entering sleep mode automatically on a specified timeout of inactivity on the I2C bus with the host system. Acked-by: Linus Walleij Acked-by: Rabin Vincent Signed-off-by: Sundar R Iyer Signed-off-by: Samuel Ortiz --- include/linux/mfd/stmpe.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h index 90faa98..39ca758 100644 --- a/include/linux/mfd/stmpe.h +++ b/include/linux/mfd/stmpe.h @@ -170,6 +170,8 @@ struct stmpe_ts_platform_data { * @blocks: bitmask of blocks to enable (use STMPE_BLOCK_*) * @irq_trigger: IRQ trigger to use for the interrupt to the host * @irq_invert_polarity: IRQ line is connected with reversed polarity + * @autosleep: bool to enable/disable stmpe autosleep + * @autosleep_timeout: inactivity timeout in milliseconds for autosleep * @irq_base: base IRQ number. %STMPE_NR_IRQS irqs will be used, or * %STMPE_NR_INTERNAL_IRQS if the GPIO driver is not used. * @gpio: GPIO-specific platform data @@ -182,6 +184,8 @@ struct stmpe_platform_data { int irq_base; unsigned int irq_trigger; bool irq_invert_polarity; + bool autosleep; + int autosleep_timeout; struct stmpe_gpio_platform_data *gpio; struct stmpe_keypad_platform_data *keypad; -- cgit v1.1 From 3b16bb539c558cd523ea380653d4bf24a8c9e833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 2 Aug 2010 11:14:17 +0200 Subject: mfd: New mc13783 function exposing flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed for the mc13783-adc driver to decide if a touch screen is connected. If so some channels are not available as generic hwmon inputs. Signed-off-by: Uwe Kleine-König Signed-off-by: Samuel Ortiz --- include/linux/mfd/mc13783.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h index 4a894f6..0fa44fb 100644 --- a/include/linux/mfd/mc13783.h +++ b/include/linux/mfd/mc13783.h @@ -21,6 +21,8 @@ int mc13783_reg_write(struct mc13783 *mc13783, unsigned int offset, u32 val); int mc13783_reg_rmw(struct mc13783 *mc13783, unsigned int offset, u32 mask, u32 val); +int mc13783_get_flags(struct mc13783 *mc13783); + int mc13783_irq_request(struct mc13783 *mc13783, int irq, irq_handler_t handler, const char *name, void *dev); int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq, -- cgit v1.1 From b6e6d54cab7633dd2216ede77ccd00cdaebd77ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 2 Aug 2010 15:48:04 +0200 Subject: mfd: Get rid of now unused mc13783 private header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds all remaining definitions that are used by the core driver to the .c file. Signed-off-by: Uwe Kleine-König Signed-off-by: Samuel Ortiz --- include/linux/mfd/mc13783-private.h | 220 ------------------------------------ 1 file changed, 220 deletions(-) delete mode 100644 include/linux/mfd/mc13783-private.h (limited to 'include') diff --git a/include/linux/mfd/mc13783-private.h b/include/linux/mfd/mc13783-private.h deleted file mode 100644 index 95cf936..0000000 --- a/include/linux/mfd/mc13783-private.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2009 Pengutronix, Sascha Hauer - * - * Initial development of this code was funded by - * Phytec Messtechnik GmbH, http://www.phytec.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. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __LINUX_MFD_MC13783_PRIV_H -#define __LINUX_MFD_MC13783_PRIV_H - -#include -#include -#include -#include - -struct mc13783 { - struct spi_device *spidev; - struct mutex lock; - int irq; - int flags; - - irq_handler_t irqhandler[MC13783_NUM_IRQ]; - void *irqdata[MC13783_NUM_IRQ]; - - /* XXX these should go as platformdata to the regulator subdevice */ - struct mc13783_regulator_init_data *regulators; - int num_regulators; -}; - -#define MC13783_REG_INTERRUPT_STATUS_0 0 -#define MC13783_REG_INTERRUPT_MASK_0 1 -#define MC13783_REG_INTERRUPT_SENSE_0 2 -#define MC13783_REG_INTERRUPT_STATUS_1 3 -#define MC13783_REG_INTERRUPT_MASK_1 4 -#define MC13783_REG_INTERRUPT_SENSE_1 5 -#define MC13783_REG_POWER_UP_MODE_SENSE 6 -#define MC13783_REG_REVISION 7 -#define MC13783_REG_SEMAPHORE 8 -#define MC13783_REG_ARBITRATION_PERIPHERAL_AUDIO 9 -#define MC13783_REG_ARBITRATION_SWITCHERS 10 -#define MC13783_REG_ARBITRATION_REGULATORS_0 11 -#define MC13783_REG_ARBITRATION_REGULATORS_1 12 -#define MC13783_REG_POWER_CONTROL_0 13 -#define MC13783_REG_POWER_CONTROL_1 14 -#define MC13783_REG_POWER_CONTROL_2 15 -#define MC13783_REG_REGEN_ASSIGNMENT 16 -#define MC13783_REG_CONTROL_SPARE 17 -#define MC13783_REG_MEMORY_A 18 -#define MC13783_REG_MEMORY_B 19 -#define MC13783_REG_RTC_TIME 20 -#define MC13783_REG_RTC_ALARM 21 -#define MC13783_REG_RTC_DAY 22 -#define MC13783_REG_RTC_DAY_ALARM 23 -#define MC13783_REG_SWITCHERS_0 24 -#define MC13783_REG_SWITCHERS_1 25 -#define MC13783_REG_SWITCHERS_2 26 -#define MC13783_REG_SWITCHERS_3 27 -#define MC13783_REG_SWITCHERS_4 28 -#define MC13783_REG_SWITCHERS_5 29 -#define MC13783_REG_REGULATOR_SETTING_0 30 -#define MC13783_REG_REGULATOR_SETTING_1 31 -#define MC13783_REG_REGULATOR_MODE_0 32 -#define MC13783_REG_REGULATOR_MODE_1 33 -#define MC13783_REG_POWER_MISCELLANEOUS 34 -#define MC13783_REG_POWER_SPARE 35 -#define MC13783_REG_AUDIO_RX_0 36 -#define MC13783_REG_AUDIO_RX_1 37 -#define MC13783_REG_AUDIO_TX 38 -#define MC13783_REG_AUDIO_SSI_NETWORK 39 -#define MC13783_REG_AUDIO_CODEC 40 -#define MC13783_REG_AUDIO_STEREO_DAC 41 -#define MC13783_REG_AUDIO_SPARE 42 -#define MC13783_REG_ADC_0 43 -#define MC13783_REG_ADC_1 44 -#define MC13783_REG_ADC_2 45 -#define MC13783_REG_ADC_3 46 -#define MC13783_REG_ADC_4 47 -#define MC13783_REG_CHARGER 48 -#define MC13783_REG_USB 49 -#define MC13783_REG_CHARGE_USB_SPARE 50 -#define MC13783_REG_LED_CONTROL_0 51 -#define MC13783_REG_LED_CONTROL_1 52 -#define MC13783_REG_LED_CONTROL_2 53 -#define MC13783_REG_LED_CONTROL_3 54 -#define MC13783_REG_LED_CONTROL_4 55 -#define MC13783_REG_LED_CONTROL_5 56 -#define MC13783_REG_SPARE 57 -#define MC13783_REG_TRIM_0 58 -#define MC13783_REG_TRIM_1 59 -#define MC13783_REG_TEST_0 60 -#define MC13783_REG_TEST_1 61 -#define MC13783_REG_TEST_2 62 -#define MC13783_REG_TEST_3 63 -#define MC13783_REG_NB 64 - -/* - * Reg Regulator Mode 0 - */ -#define MC13783_REGCTRL_VAUDIO_EN (1 << 0) -#define MC13783_REGCTRL_VAUDIO_STBY (1 << 1) -#define MC13783_REGCTRL_VAUDIO_MODE (1 << 2) -#define MC13783_REGCTRL_VIOHI_EN (1 << 3) -#define MC13783_REGCTRL_VIOHI_STBY (1 << 4) -#define MC13783_REGCTRL_VIOHI_MODE (1 << 5) -#define MC13783_REGCTRL_VIOLO_EN (1 << 6) -#define MC13783_REGCTRL_VIOLO_STBY (1 << 7) -#define MC13783_REGCTRL_VIOLO_MODE (1 << 8) -#define MC13783_REGCTRL_VDIG_EN (1 << 9) -#define MC13783_REGCTRL_VDIG_STBY (1 << 10) -#define MC13783_REGCTRL_VDIG_MODE (1 << 11) -#define MC13783_REGCTRL_VGEN_EN (1 << 12) -#define MC13783_REGCTRL_VGEN_STBY (1 << 13) -#define MC13783_REGCTRL_VGEN_MODE (1 << 14) -#define MC13783_REGCTRL_VRFDIG_EN (1 << 15) -#define MC13783_REGCTRL_VRFDIG_STBY (1 << 16) -#define MC13783_REGCTRL_VRFDIG_MODE (1 << 17) -#define MC13783_REGCTRL_VRFREF_EN (1 << 18) -#define MC13783_REGCTRL_VRFREF_STBY (1 << 19) -#define MC13783_REGCTRL_VRFREF_MODE (1 << 20) -#define MC13783_REGCTRL_VRFCP_EN (1 << 21) -#define MC13783_REGCTRL_VRFCP_STBY (1 << 22) -#define MC13783_REGCTRL_VRFCP_MODE (1 << 23) - -/* - * Reg Regulator Mode 1 - */ -#define MC13783_REGCTRL_VSIM_EN (1 << 0) -#define MC13783_REGCTRL_VSIM_STBY (1 << 1) -#define MC13783_REGCTRL_VSIM_MODE (1 << 2) -#define MC13783_REGCTRL_VESIM_EN (1 << 3) -#define MC13783_REGCTRL_VESIM_STBY (1 << 4) -#define MC13783_REGCTRL_VESIM_MODE (1 << 5) -#define MC13783_REGCTRL_VCAM_EN (1 << 6) -#define MC13783_REGCTRL_VCAM_STBY (1 << 7) -#define MC13783_REGCTRL_VCAM_MODE (1 << 8) -#define MC13783_REGCTRL_VRFBG_EN (1 << 9) -#define MC13783_REGCTRL_VRFBG_STBY (1 << 10) -#define MC13783_REGCTRL_VVIB_EN (1 << 11) -#define MC13783_REGCTRL_VRF1_EN (1 << 12) -#define MC13783_REGCTRL_VRF1_STBY (1 << 13) -#define MC13783_REGCTRL_VRF1_MODE (1 << 14) -#define MC13783_REGCTRL_VRF2_EN (1 << 15) -#define MC13783_REGCTRL_VRF2_STBY (1 << 16) -#define MC13783_REGCTRL_VRF2_MODE (1 << 17) -#define MC13783_REGCTRL_VMMC1_EN (1 << 18) -#define MC13783_REGCTRL_VMMC1_STBY (1 << 19) -#define MC13783_REGCTRL_VMMC1_MODE (1 << 20) -#define MC13783_REGCTRL_VMMC2_EN (1 << 21) -#define MC13783_REGCTRL_VMMC2_STBY (1 << 22) -#define MC13783_REGCTRL_VMMC2_MODE (1 << 23) - -/* - * Reg Regulator Misc. - */ -#define MC13783_REGCTRL_GPO1_EN (1 << 6) -#define MC13783_REGCTRL_GPO2_EN (1 << 8) -#define MC13783_REGCTRL_GPO3_EN (1 << 10) -#define MC13783_REGCTRL_GPO4_EN (1 << 12) -#define MC13783_REGCTRL_VIBPINCTRL (1 << 14) - -/* - * Reg Switcher 4 - */ -#define MC13783_SWCTRL_SW1A_MODE (1 << 0) -#define MC13783_SWCTRL_SW1A_STBY_MODE (1 << 2) -#define MC13783_SWCTRL_SW1A_DVS_SPEED (1 << 6) -#define MC13783_SWCTRL_SW1A_PANIC_MODE (1 << 8) -#define MC13783_SWCTRL_SW1A_SOFTSTART (1 << 9) -#define MC13783_SWCTRL_SW1B_MODE (1 << 10) -#define MC13783_SWCTRL_SW1B_STBY_MODE (1 << 12) -#define MC13783_SWCTRL_SW1B_DVS_SPEED (1 << 14) -#define MC13783_SWCTRL_SW1B_PANIC_MODE (1 << 16) -#define MC13783_SWCTRL_SW1B_SOFTSTART (1 << 17) -#define MC13783_SWCTRL_PLL_EN (1 << 18) -#define MC13783_SWCTRL_PLL_FACTOR (1 << 19) - -/* - * Reg Switcher 5 - */ -#define MC13783_SWCTRL_SW2A_MODE (1 << 0) -#define MC13783_SWCTRL_SW2A_STBY_MODE (1 << 2) -#define MC13783_SWCTRL_SW2A_DVS_SPEED (1 << 6) -#define MC13783_SWCTRL_SW2A_PANIC_MODE (1 << 8) -#define MC13783_SWCTRL_SW2A_SOFTSTART (1 << 9) -#define MC13783_SWCTRL_SW2B_MODE (1 << 10) -#define MC13783_SWCTRL_SW2B_STBY_MODE (1 << 12) -#define MC13783_SWCTRL_SW2B_DVS_SPEED (1 << 14) -#define MC13783_SWCTRL_SW2B_PANIC_MODE (1 << 16) -#define MC13783_SWCTRL_SW2B_SOFTSTART (1 << 17) -#define MC13783_SWSET_SW3 (1 << 18) -#define MC13783_SWCTRL_SW3_EN (1 << 20) -#define MC13783_SWCTRL_SW3_STBY (1 << 21) -#define MC13783_SWCTRL_SW3_MODE (1 << 22) - -static inline int mc13783_set_bits(struct mc13783 *mc13783, unsigned int offset, - u32 mask, u32 val) -{ - int ret; - mc13783_lock(mc13783); - ret = mc13783_reg_rmw(mc13783, offset, mask, val); - mc13783_unlock(mc13783); - - return ret; -} - -#endif /* __LINUX_MFD_MC13783_PRIV_H */ -- cgit v1.1 From c6c193326384aecfd668c8f271799a44dbc74c1a Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Wed, 11 Aug 2010 01:11:04 +0200 Subject: mfd: Add TPS6586x driver Add mfd core driver for TPS6586x PMICs family. The driver provides I/O access for the sub-device drivers and performs regstration of the sub-devices based on the platform requirements. In addition it implements GPIOlib interface for the chip GPIOs. TODO: - add interrupt support - add platform data for PWM, backlight leds and charger Signed-off-by: Mike Rapoport Signed-off-by: Mike Rapoport Signed-off-by: Samuel Ortiz --- include/linux/mfd/tps6586x.h | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 include/linux/mfd/tps6586x.h (limited to 'include') diff --git a/include/linux/mfd/tps6586x.h b/include/linux/mfd/tps6586x.h new file mode 100644 index 0000000..772b3ae --- /dev/null +++ b/include/linux/mfd/tps6586x.h @@ -0,0 +1,47 @@ +#ifndef __LINUX_MFD_TPS6586X_H +#define __LINUX_MFD_TPS6586X_H + +enum { + TPS6586X_ID_SM_0, + TPS6586X_ID_SM_1, + TPS6586X_ID_SM_2, + TPS6586X_ID_LDO_0, + TPS6586X_ID_LDO_1, + TPS6586X_ID_LDO_2, + TPS6586X_ID_LDO_3, + TPS6586X_ID_LDO_4, + TPS6586X_ID_LDO_5, + TPS6586X_ID_LDO_6, + TPS6586X_ID_LDO_7, + TPS6586X_ID_LDO_8, + TPS6586X_ID_LDO_9, + TPS6586X_ID_LDO_RTC, +}; + +struct tps6586x_subdev_info { + int id; + const char *name; + void *platform_data; +}; + +struct tps6586x_platform_data { + int num_subdevs; + struct tps6586x_subdev_info *subdevs; + + int gpio_base; +}; + +/* + * NOTE: the functions below are not intended for use outside + * of the TPS6586X sub-device drivers + */ +extern int tps6586x_write(struct device *dev, int reg, uint8_t val); +extern int tps6586x_writes(struct device *dev, int reg, int len, uint8_t *val); +extern int tps6586x_read(struct device *dev, int reg, uint8_t *val); +extern int tps6586x_reads(struct device *dev, int reg, int len, uint8_t *val); +extern int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask); +extern int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask); +extern int tps6586x_update(struct device *dev, int reg, uint8_t val, + uint8_t mask); + +#endif /*__LINUX_MFD_TPS6586X_H */ -- cgit v1.1 From 0a7992c90828a65281c3c9cf180be3b432d277b2 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 11 Aug 2010 14:17:29 -0700 Subject: acpi: fix bogus preemption logic The ACPI_PREEMPTION_POINT() logic was introduced in commit 8bd108d (ACPICA: add preemption point after each opcode parse). The follow up commits abe1dfab6, 138d15692, c084ca70 tried to fix the preemption logic back and forth, but nobody noticed that the usage of in_atomic_preempt_off() in that context is wrong. The check which guards the call of cond_resched() is: if (!in_atomic_preempt_off() && !irqs_disabled()) in_atomic_preempt_off() is not intended for general use as the comment above the macro definition clearly says: * Check whether we were atomic before we did preempt_disable(): * (used by the scheduler, *after* releasing the kernel lock) On a CONFIG_PREEMPT=n kernel the usage of in_atomic_preempt_off() works by accident, but with CONFIG_PREEMPT=y it's just broken. The whole purpose of the ACPI_PREEMPTION_POINT() is to reduce the latency on a CONFIG_PREEMPT=n kernel, so make ACPI_PREEMPTION_POINT() depend on CONFIG_PREEMPT=n and remove the in_atomic_preempt_off() check. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=16210 [akpm@linux-foundation.org: fix build] Signed-off-by: Thomas Gleixner Cc: Len Brown Cc: Francois Valenduc Cc: Lin Ming Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/acpi/platform/aclinux.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index e5039a2..103f08a 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -148,13 +148,17 @@ static inline void *acpi_os_acquire_object(acpi_cache_t * cache) #define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a) #define ACPI_FREE(a) kfree(a) -/* Used within ACPICA to show where it is safe to preempt execution */ -#include +#ifndef CONFIG_PREEMPT +/* + * Used within ACPICA to show where it is safe to preempt execution + * when CONFIG_PREEMPT=n + */ #define ACPI_PREEMPTION_POINT() \ do { \ - if (!in_atomic_preempt_off() && !irqs_disabled()) \ + if (!irqs_disabled()) \ cond_resched(); \ } while (0) +#endif #endif /* __KERNEL__ */ -- cgit v1.1 From 16c4042f08919f447d6b2a55679546c9b97c7264 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Wed, 11 Aug 2010 14:17:39 -0700 Subject: writeback: avoid unnecessary calculation of bdi dirty thresholds Split get_dirty_limits() into global_dirty_limits()+bdi_dirty_limit(), so that the latter can be avoided when under global dirty background threshold (which is the normal state for most systems). Signed-off-by: Wu Fengguang Cc: Peter Zijlstra Cc: Christoph Hellwig Cc: Dave Chinner Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/writeback.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/writeback.h b/include/linux/writeback.h index c24eca7..72a5d64 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -124,8 +124,9 @@ struct ctl_table; int dirty_writeback_centisecs_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); -void get_dirty_limits(unsigned long *pbackground, unsigned long *pdirty, - unsigned long *pbdi_dirty, struct backing_dev_info *bdi); +void global_dirty_limits(unsigned long *pbackground, unsigned long *pdirty); +unsigned long bdi_dirty_limit(struct backing_dev_info *bdi, + unsigned long dirty); void page_writeback_init(void); void balance_dirty_pages_ratelimited_nr(struct address_space *mapping, -- cgit v1.1 From 81d73a32d775ae9674ea6edf0b5b721fc3bc57d9 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 11 Aug 2010 14:17:44 -0700 Subject: mm: fix writeback_in_progress() Commit 83ba7b071f3 ("writeback: simplify the write back thread queue") broke writeback_in_progress() as in that commit we started to remove work items from the list at the moment we start working on them and not at the moment they are finished. Thus if the flusher thread was doing some work but there was no other work queued, writeback_in_progress() returned false. This could in particular cause unnecessary queueing of background writeback from balance_dirty_pages() or writeout work from writeback_sb_if_idle(). This patch fixes the problem by introducing a bit in the bdi state which indicates that the flusher thread is processing some work and uses this bit for writeback_in_progress() test. NOTE: Both callsites of writeback_in_progress() (namely, writeback_inodes_sb_if_idle() and balance_dirty_pages()) would actually need a different information than what writeback_in_progress() provides. They would need to know whether *the kind of writeback they are going to submit* is already queued. But this information isn't that simple to provide so let's fix writeback_in_progress() for the time being. Signed-off-by: Jan Kara Cc: Christoph Hellwig Cc: Wu Fengguang Acked-by: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/backing-dev.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index 7628219..35b0074 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -31,6 +31,7 @@ enum bdi_state { BDI_async_congested, /* The async (write) queue is getting full */ BDI_sync_congested, /* The sync queue is getting full */ BDI_registered, /* bdi_register() was done */ + BDI_writeback_running, /* Writeback is in progress */ BDI_unused, /* Available bits start here */ }; -- cgit v1.1 From dfe86cba7676d58db8de7e623f5e72f1b0d3ca35 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 11 Aug 2010 14:17:46 -0700 Subject: mmc: add erase, secure erase, trim and secure trim operations SD/MMC cards tend to support an erase operation. In addition, eMMC v4.4 cards can support secure erase, trim and secure trim operations that are all variants of the basic erase command. SD/MMC device attributes "erase_size" and "preferred_erase_size" have been added. "erase_size" is the minimum size, in bytes, of an erase operation. For MMC, "erase_size" is the erase group size reported by the card. Note that "erase_size" does not apply to trim or secure trim operations where the minimum size is always one 512 byte sector. For SD, "erase_size" is 512 if the card is block-addressed, 0 otherwise. SD/MMC cards can erase an arbitrarily large area up to and including the whole card. When erasing a large area it may be desirable to do it in smaller chunks for three reasons: 1. A single erase command will make all other I/O on the card wait. This is not a problem if the whole card is being erased, but erasing one partition will make I/O for another partition on the same card wait for the duration of the erase - which could be a several minutes. 2. To be able to inform the user of erase progress. 3. The erase timeout becomes too large to be very useful. Because the erase timeout contains a margin which is multiplied by the size of the erase area, the value can end up being several minutes for large areas. "erase_size" is not the most efficient unit to erase (especially for SD where it is just one sector), hence "preferred_erase_size" provides a good chunk size for erasing large areas. For MMC, "preferred_erase_size" is the high-capacity erase size if a card specifies one, otherwise it is based on the capacity of the card. For SD, "preferred_erase_size" is the allocation unit size specified by the card. "preferred_erase_size" is in bytes. Signed-off-by: Adrian Hunter Acked-by: Jens Axboe Cc: Kyungmin Park Cc: Madhusudhan Chikkature Cc: Christoph Hellwig Cc: Ben Gardiner Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmc/card.h | 20 ++++++++++++++++++++ include/linux/mmc/core.h | 19 +++++++++++++++++++ include/linux/mmc/host.h | 1 + include/linux/mmc/mmc.h | 26 +++++++++++++++++++------- include/linux/mmc/sd.h | 5 +++++ 5 files changed, 64 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 4d893ea..6b75250 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -31,6 +31,7 @@ struct mmc_csd { unsigned int tacc_ns; unsigned int r2w_factor; unsigned int max_dtr; + unsigned int erase_size; /* In sectors */ unsigned int read_blkbits; unsigned int write_blkbits; unsigned int capacity; @@ -42,9 +43,16 @@ struct mmc_csd { struct mmc_ext_csd { u8 rev; + u8 erase_group_def; + u8 sec_feature_support; unsigned int sa_timeout; /* Units: 100ns */ unsigned int hs_max_dtr; unsigned int sectors; + unsigned int hc_erase_size; /* In sectors */ + unsigned int hc_erase_timeout; /* In milliseconds */ + unsigned int sec_trim_mult; /* Secure trim multiplier */ + unsigned int sec_erase_mult; /* Secure erase multiplier */ + unsigned int trim_timeout; /* In milliseconds */ }; struct sd_scr { @@ -54,6 +62,12 @@ struct sd_scr { #define SD_SCR_BUS_WIDTH_4 (1<<2) }; +struct sd_ssr { + unsigned int au; /* In sectors */ + unsigned int erase_timeout; /* In milliseconds */ + unsigned int erase_offset; /* In milliseconds */ +}; + struct sd_switch_caps { unsigned int hs_max_dtr; }; @@ -106,6 +120,11 @@ struct mmc_card { #define MMC_QUIRK_NONSTD_SDIO (1<<2) /* non-standard SDIO card attached */ /* (missing CIA registers) */ + unsigned int erase_size; /* erase size in sectors */ + unsigned int erase_shift; /* if erase unit is power 2 */ + unsigned int pref_erase; /* in sectors */ + u8 erased_byte; /* value of erased bytes */ + u32 raw_cid[4]; /* raw card CID */ u32 raw_csd[4]; /* raw card CSD */ u32 raw_scr[2]; /* raw card SCR */ @@ -113,6 +132,7 @@ struct mmc_card { struct mmc_csd csd; /* card specific */ struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */ struct sd_scr scr; /* extra SD information */ + struct sd_ssr ssr; /* yet more SD information */ struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ unsigned int sdio_funcs; /* number of SDIO functions */ diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index e4898e9..7429033 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -92,6 +92,8 @@ struct mmc_command { * actively failing requests */ + unsigned int erase_timeout; /* in milliseconds */ + struct mmc_data *data; /* data segment associated with cmd */ struct mmc_request *mrq; /* associated request */ }; @@ -134,6 +136,23 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, struct mmc_command *, int); +#define MMC_ERASE_ARG 0x00000000 +#define MMC_SECURE_ERASE_ARG 0x80000000 +#define MMC_TRIM_ARG 0x00000001 +#define MMC_SECURE_TRIM1_ARG 0x80000001 +#define MMC_SECURE_TRIM2_ARG 0x80008000 + +#define MMC_SECURE_ARGS 0x80000000 +#define MMC_TRIM_ARGS 0x00008001 + +extern int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, + unsigned int arg); +extern int mmc_can_erase(struct mmc_card *card); +extern int mmc_can_trim(struct mmc_card *card); +extern int mmc_can_secure_erase_trim(struct mmc_card *card); +extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, + unsigned int nr); + extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 513ff03..1575b52 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -156,6 +156,7 @@ struct mmc_host { #define MMC_CAP_DISABLE (1 << 7) /* Can the host be disabled */ #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 */ mmc_pm_flag_t pm_caps; /* supported pm features */ diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 52ce988..dd11ae5 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -251,13 +251,21 @@ struct _mmc_csd { * EXT_CSD fields */ -#define EXT_CSD_BUS_WIDTH 183 /* R/W */ -#define EXT_CSD_HS_TIMING 185 /* R/W */ -#define EXT_CSD_CARD_TYPE 196 /* RO */ -#define EXT_CSD_STRUCTURE 194 /* RO */ -#define EXT_CSD_REV 192 /* RO */ -#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ -#define EXT_CSD_S_A_TIMEOUT 217 +#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ +#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */ +#define EXT_CSD_BUS_WIDTH 183 /* R/W */ +#define EXT_CSD_HS_TIMING 185 /* R/W */ +#define EXT_CSD_REV 192 /* RO */ +#define EXT_CSD_STRUCTURE 194 /* RO */ +#define EXT_CSD_CARD_TYPE 196 /* RO */ +#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ +#define EXT_CSD_S_A_TIMEOUT 217 /* RO */ +#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */ +#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ +#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */ +#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */ +#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */ +#define EXT_CSD_TRIM_MULT 232 /* RO */ /* * EXT_CSD field definitions @@ -275,6 +283,10 @@ struct _mmc_csd { #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ +#define EXT_CSD_SEC_ER_EN BIT(0) +#define EXT_CSD_SEC_BD_BLK_EN BIT(2) +#define EXT_CSD_SEC_GB_CL_EN BIT(4) + /* * MMC_SWITCH access modes */ diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index f310062..3fd85e0 100644 --- a/include/linux/mmc/sd.h +++ b/include/linux/mmc/sd.h @@ -21,8 +21,13 @@ /* class 10 */ #define SD_SWITCH 6 /* adtc [31:0] See below R1 */ + /* class 5 */ +#define SD_ERASE_WR_BLK_START 32 /* ac [31:0] data addr R1 */ +#define SD_ERASE_WR_BLK_END 33 /* ac [31:0] data addr R1 */ + /* Application commands */ #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ +#define SD_APP_SD_STATUS 13 /* adtc R1 */ #define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ #define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ #define SD_APP_SEND_SCR 51 /* adtc R1 */ -- cgit v1.1 From 8d57a98ccd0b4489003473979da8f5a1363ba7a3 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 11 Aug 2010 14:17:49 -0700 Subject: block: add secure discard Secure discard is the same as discard except that all copies of the discarded sectors (perhaps created by garbage collection) must also be erased. Signed-off-by: Adrian Hunter Acked-by: Jens Axboe Cc: Kyungmin Park Cc: Madhusudhan Chikkature Cc: Christoph Hellwig Cc: Ben Gardiner Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/blk_types.h | 2 ++ include/linux/blkdev.h | 7 ++++++- include/linux/fs.h | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 5369177..ca83a97 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -150,6 +150,7 @@ enum rq_flag_bits { __REQ_FLUSH, /* request for cache flush */ __REQ_IO_STAT, /* account I/O stat */ __REQ_MIXED_MERGE, /* merge of different types, fail separately */ + __REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */ __REQ_NR_BITS, /* stops here */ }; @@ -190,5 +191,6 @@ enum rq_flag_bits { #define REQ_FLUSH (1 << __REQ_FLUSH) #define REQ_IO_STAT (1 << __REQ_IO_STAT) #define REQ_MIXED_MERGE (1 << __REQ_MIXED_MERGE) +#define REQ_SECURE (1 << __REQ_SECURE) #endif /* __LINUX_BLK_TYPES_H */ diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 89c855c..2c54906 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -389,6 +389,7 @@ struct request_queue #define QUEUE_FLAG_DISCARD 16 /* supports DISCARD */ #define QUEUE_FLAG_NOXMERGES 17 /* No extended merges */ #define QUEUE_FLAG_ADD_RANDOM 18 /* Contributes to random pool */ +#define QUEUE_FLAG_SECDISCARD 19 /* supports SECDISCARD */ #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ (1 << QUEUE_FLAG_CLUSTER) | \ @@ -524,6 +525,8 @@ enum { #define blk_queue_stackable(q) \ test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags) #define blk_queue_discard(q) test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags) +#define blk_queue_secdiscard(q) (blk_queue_discard(q) && \ + test_bit(QUEUE_FLAG_SECDISCARD, &(q)->queue_flags)) #define blk_noretry_request(rq) \ ((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \ @@ -918,10 +921,12 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt, } enum{ BLKDEV_WAIT, /* wait for completion */ - BLKDEV_BARRIER, /*issue request with barrier */ + BLKDEV_BARRIER, /* issue request with barrier */ + BLKDEV_SECURE, /* secure discard */ }; #define BLKDEV_IFL_WAIT (1 << BLKDEV_WAIT) #define BLKDEV_IFL_BARRIER (1 << BLKDEV_BARRIER) +#define BLKDEV_IFL_SECURE (1 << BLKDEV_SECURE) extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *, unsigned long); extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector, diff --git a/include/linux/fs.h b/include/linux/fs.h index 267d026..7a0625e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -174,6 +174,7 @@ struct inodes_stat_t { */ #define DISCARD_NOBARRIER (WRITE | REQ_DISCARD) #define DISCARD_BARRIER (WRITE | REQ_DISCARD | REQ_HARDBARRIER) +#define DISCARD_SECURE (DISCARD_NOBARRIER | REQ_SECURE) #define SEL_IN 1 #define SEL_OUT 2 @@ -317,6 +318,7 @@ struct inodes_stat_t { #define BLKALIGNOFF _IO(0x12,122) #define BLKPBSZGET _IO(0x12,123) #define BLKDISCARDZEROES _IO(0x12,124) +#define BLKSECDISCARD _IO(0x12,125) #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ #define FIBMAP _IO(0x00,1) /* bmap access */ -- cgit v1.1 From 12fdff3fc2483f906ae6404a6e8dcf2550310b6f Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 12 Aug 2010 16:54:57 +0100 Subject: Add a dummy printk function for the maintenance of unused printks Add a dummy printk function for the maintenance of unused printks through gcc format checking, and also so that side-effect checking is maintained too. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- include/linux/kernel.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index d848cb8..2b0a35e 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -306,6 +306,13 @@ static inline void log_buf_kexec_setup(void) } #endif +/* + * Dummy printk for disabled debugging statements to use whilst maintaining + * gcc's format and side-effect checking. + */ +static inline __attribute__ ((format (printf, 1, 2))) +int no_printk(const char *s, ...) { return 0; } + extern int printk_needs_cpu(int cpu); extern void printk_tick(void); -- cgit v1.1 From 4936a3b90d79dd8775c6ac23c2cf2dcebe29abde Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Aug 2010 14:20:10 -0700 Subject: x86/hpet: Use the FSEC_PER_SEC constant for femto-second periods The current computation, introduced with f12a15be63, of FSEC_PER_SEC using the multiplication of (FSEC_PER_NSEC * NSEC_PER_SEC) is performed only with 32bit integers on small machines, resulting in an overflow and a *very* short intervals being programmed. An interrupt storm follows. Note that we also have to specify FSEC_PER_SEC as being long long to overcome the same limitations. Signed-off-by: Chris Wilson Signed-off-by: John Stultz Cc: Thomas Gleixner Acked-by: Ingo Molnar Acked-by: H. Peter Anvin Signed-off-by: Linus Torvalds --- include/linux/time.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/time.h b/include/linux/time.h index cb34e35..1261270 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -38,7 +38,7 @@ extern struct timezone sys_tz; #define NSEC_PER_MSEC 1000000L #define USEC_PER_SEC 1000000L #define NSEC_PER_SEC 1000000000L -#define FSEC_PER_SEC 1000000000000000L +#define FSEC_PER_SEC 1000000000000000LL #define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) -- cgit v1.1 From 2069601b3f0ea38170d4b509b89f3ca0a373bdc1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 12 Aug 2010 14:23:04 -0700 Subject: Revert "fsnotify: store struct file not struct path" This reverts commit 3bcf3860a4ff9bbc522820b4b765e65e4deceb3e (and the accompanying commit c1e5c954020e "vfs/fsnotify: fsnotify_close can delay the final work in fput" that was a horribly ugly hack to make it work at all). The 'struct file' approach not only causes that disgusting hack, it somehow breaks pulseaudio, probably due to some other subtlety with f_count handling. Fix up various conflicts due to later fsnotify work. Signed-off-by: Linus Torvalds --- include/linux/fsnotify.h | 37 +++++++++++++++++++++---------------- include/linux/fsnotify_backend.h | 16 ++++++++-------- 2 files changed, 29 insertions(+), 24 deletions(-) (limited to 'include') diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index e4e2204..59d0df4 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -26,18 +26,19 @@ static inline void fsnotify_d_instantiate(struct dentry *dentry, } /* Notify this dentry's parent about a child's events. */ -static inline void fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask) +static inline void fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) { if (!dentry) - dentry = file->f_path.dentry; + dentry = path->dentry; - __fsnotify_parent(file, dentry, mask); + __fsnotify_parent(path, dentry, mask); } /* simple call site for access decisions */ static inline int fsnotify_perm(struct file *file, int mask) { - struct inode *inode = file->f_path.dentry->d_inode; + struct path *path = &file->f_path; + struct inode *inode = path->dentry->d_inode; __u32 fsnotify_mask = 0; if (file->f_mode & FMODE_NONOTIFY) @@ -51,7 +52,7 @@ static inline int fsnotify_perm(struct file *file, int mask) else BUG(); - return fsnotify(inode, fsnotify_mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); + return fsnotify(inode, fsnotify_mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); } /* @@ -186,15 +187,16 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) */ static inline void fsnotify_access(struct file *file) { - struct inode *inode = file->f_path.dentry->d_inode; + struct path *path = &file->f_path; + struct inode *inode = path->dentry->d_inode; __u32 mask = FS_ACCESS; if (S_ISDIR(inode->i_mode)) mask |= FS_IN_ISDIR; if (!(file->f_mode & FMODE_NONOTIFY)) { - fsnotify_parent(file, NULL, mask); - fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); + fsnotify_parent(path, NULL, mask); + fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); } } @@ -203,15 +205,16 @@ static inline void fsnotify_access(struct file *file) */ static inline void fsnotify_modify(struct file *file) { - struct inode *inode = file->f_path.dentry->d_inode; + struct path *path = &file->f_path; + struct inode *inode = path->dentry->d_inode; __u32 mask = FS_MODIFY; if (S_ISDIR(inode->i_mode)) mask |= FS_IN_ISDIR; if (!(file->f_mode & FMODE_NONOTIFY)) { - fsnotify_parent(file, NULL, mask); - fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); + fsnotify_parent(path, NULL, mask); + fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); } } @@ -220,15 +223,16 @@ static inline void fsnotify_modify(struct file *file) */ static inline void fsnotify_open(struct file *file) { - struct inode *inode = file->f_path.dentry->d_inode; + struct path *path = &file->f_path; + struct inode *inode = path->dentry->d_inode; __u32 mask = FS_OPEN; if (S_ISDIR(inode->i_mode)) mask |= FS_IN_ISDIR; if (!(file->f_mode & FMODE_NONOTIFY)) { - fsnotify_parent(file, NULL, mask); - fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); + fsnotify_parent(path, NULL, mask); + fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); } } @@ -237,6 +241,7 @@ static inline void fsnotify_open(struct file *file) */ static inline void fsnotify_close(struct file *file) { + struct path *path = &file->f_path; struct inode *inode = file->f_path.dentry->d_inode; fmode_t mode = file->f_mode; __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE; @@ -245,8 +250,8 @@ static inline void fsnotify_close(struct file *file) mask |= FS_IN_ISDIR; if (!(file->f_mode & FMODE_NONOTIFY)) { - fsnotify_parent(file, NULL, mask); - fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); + fsnotify_parent(path, NULL, mask); + fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); } } diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 9bbfd72..ed36fb5 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -203,20 +203,20 @@ struct fsnotify_event { /* to_tell may ONLY be dereferenced during handle_event(). */ struct inode *to_tell; /* either the inode the event happened to or its parent */ /* - * depending on the event type we should have either a file or inode - * We hold a reference on file, but NOT on inode. Since we have the ref on - * the file, it may be dereferenced at any point during this object's + * depending on the event type we should have either a path or inode + * We hold a reference on path, but NOT on inode. Since we have the ref on + * the path, it may be dereferenced at any point during this object's * lifetime. That reference is dropped when this object's refcnt hits - * 0. If this event contains an inode instead of a file, the inode may + * 0. If this event contains an inode instead of a path, the inode may * ONLY be used during handle_event(). */ union { - struct file *file; + struct path path; struct inode *inode; }; /* when calling fsnotify tell it if the data is a path or inode */ #define FSNOTIFY_EVENT_NONE 0 -#define FSNOTIFY_EVENT_FILE 1 +#define FSNOTIFY_EVENT_PATH 1 #define FSNOTIFY_EVENT_INODE 2 int data_type; /* which of the above union we have */ atomic_t refcnt; /* how many groups still are using/need to send this event */ @@ -293,7 +293,7 @@ struct fsnotify_mark { /* main fsnotify call to send events */ extern int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const unsigned char *name, u32 cookie); -extern void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask); +extern void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask); extern void __fsnotify_inode_delete(struct inode *inode); extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); extern u32 fsnotify_get_cookie(void); @@ -422,7 +422,7 @@ static inline int fsnotify(struct inode *to_tell, __u32 mask, void *data, int da return 0; } -static inline void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask) +static inline void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) {} static inline void __fsnotify_inode_delete(struct inode *inode) -- cgit v1.1