mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Compare commits
147 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6fd41e29d | ||
|
|
8cb3ed17cb | ||
|
|
4c7527821c | ||
|
|
14d01ff534 | ||
|
|
0b001b2eda | ||
|
|
5dfcc87fd7 | ||
|
|
24114504c4 | ||
|
|
15ce92861f | ||
|
|
d035953e59 | ||
|
|
87adf1c66c | ||
|
|
14f69ec706 | ||
|
|
d525e8ab02 | ||
|
|
d72c0842ff | ||
|
|
4815053aba | ||
|
|
a39f752143 | ||
|
|
0c1a98c814 | ||
|
|
5b397377e9 | ||
|
|
98c9942aca | ||
|
|
65450aa645 | ||
|
|
ddf23b3fc6 | ||
|
|
e0b6d65be5 | ||
|
|
14c7cca780 | ||
|
|
fc61ccd35f | ||
|
|
de4ed0c111 | ||
|
|
c8814df3a5 | ||
|
|
6a02a33067 | ||
|
|
5b5cfc3674 | ||
|
|
313c68e644 | ||
|
|
55c53e1f24 | ||
|
|
4264a8b638 | ||
|
|
707b38a00b | ||
|
|
6a53747be5 | ||
|
|
d7a210f3d3 | ||
|
|
d0a77454c7 | ||
|
|
6c6d8deb5d | ||
|
|
1f51b001cc | ||
|
|
c338bfb5ec | ||
|
|
290a1cc4f7 | ||
|
|
27a7b260f7 | ||
|
|
079fa166a2 | ||
|
|
19d5f834d6 | ||
|
|
94007751bb | ||
|
|
ed2888e906 | ||
|
|
5307f6d5fb | ||
|
|
a6a5ed0dd3 | ||
|
|
0d20fbbe82 | ||
|
|
0ec26fd069 | ||
|
|
7caaf7efb9 | ||
|
|
83a497cab1 | ||
|
|
55a01f6f68 | ||
|
|
909d6e0cb6 | ||
|
|
0e83bb4eee | ||
|
|
1bf2706601 | ||
|
|
17c8b96093 | ||
|
|
cfd8be088e | ||
|
|
ffbc559b06 | ||
|
|
e4e436e0bd | ||
|
|
9ba365438a | ||
|
|
3d0283ebc8 | ||
|
|
4dcaadc319 | ||
|
|
4fbcc42dc4 | ||
|
|
bff747c58c | ||
|
|
d2f152878d | ||
|
|
79016f6488 | ||
|
|
e81b693c01 | ||
|
|
b0fb422281 | ||
|
|
54d6d53744 | ||
|
|
4fc1d39e07 | ||
|
|
28c51ee3da | ||
|
|
1154526753 | ||
|
|
768b56f598 | ||
|
|
882aba0105 | ||
|
|
897a6a1a14 | ||
|
|
9086617ea3 | ||
|
|
dde58cfcc3 | ||
|
|
c08748005d | ||
|
|
810198bc9c | ||
|
|
bac7e6ecf6 | ||
|
|
bb9ea77846 | ||
|
|
96219c3a25 | ||
|
|
048e29cff9 | ||
|
|
406bd18a7a | ||
|
|
7a703aded9 | ||
|
|
126caf1376 | ||
|
|
f020b007d5 | ||
|
|
d91aae1e52 | ||
|
|
ff71c182f4 | ||
|
|
51b8b4fb32 | ||
|
|
73f507171c | ||
|
|
f88657ce3f | ||
|
|
b49d8b5d70 | ||
|
|
45089142b1 | ||
|
|
5441ae5eb3 | ||
|
|
b06947b500 | ||
|
|
5204f5e3f5 | ||
|
|
d7cb666709 | ||
|
|
82babbb361 | ||
|
|
7404368c22 | ||
|
|
3b3d5b0f85 | ||
|
|
da063d2609 | ||
|
|
1df726ef0a | ||
|
|
876355014c | ||
|
|
10167873a4 | ||
|
|
fb492c9160 | ||
|
|
e33acde911 | ||
|
|
f1ca1512e7 | ||
|
|
4862571308 | ||
|
|
ed467e69f1 | ||
|
|
d198d49914 | ||
|
|
d312ae878b | ||
|
|
aca420bc51 | ||
|
|
49bb1e6195 | ||
|
|
93c712f99d | ||
|
|
b91df1593e | ||
|
|
50a50f9248 | ||
|
|
778e277cb8 | ||
|
|
08c14071fd | ||
|
|
20afc60f89 | ||
|
|
7f310a5d4e | ||
|
|
3b217116ed | ||
|
|
a8d757ef07 | ||
|
|
feff8fa007 | ||
|
|
9c40cef2b7 | ||
|
|
c259e01a1e | ||
|
|
66506f7617 | ||
|
|
7e72c68634 | ||
|
|
a7402deb32 | ||
|
|
6d1db07779 | ||
|
|
35d851df23 | ||
|
|
e21757a057 | ||
|
|
259a187ade | ||
|
|
450a37d2ec | ||
|
|
9c5f560173 | ||
|
|
b1cbdb00da | ||
|
|
c956b753e7 | ||
|
|
9efabc8476 | ||
|
|
016f1c5440 | ||
|
|
795858dbd2 | ||
|
|
938f97bcf1 | ||
|
|
34d623d113 | ||
|
|
dec35d19c4 | ||
|
|
bf6ed027bc | ||
|
|
6af7e471e5 | ||
|
|
ea7802f630 | ||
|
|
971c90bfa2 | ||
|
|
4f6fdf0868 | ||
|
|
5185352c16 |
@@ -1455,7 +1455,7 @@ Applicable to the H264 encoder.</entry>
|
|||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
<row>
|
<row id="v4l2-mpeg-video-h264-vui-sar-idc">
|
||||||
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC</constant> </entry>
|
||||||
<entry>enum v4l2_mpeg_video_h264_vui_sar_idc</entry>
|
<entry>enum v4l2_mpeg_video_h264_vui_sar_idc</entry>
|
||||||
</row>
|
</row>
|
||||||
@@ -1561,7 +1561,7 @@ Applicable to the H264 encoder.</entry>
|
|||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
<row>
|
<row id="v4l2-mpeg-video-h264-level">
|
||||||
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_LEVEL</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_LEVEL</constant> </entry>
|
||||||
<entry>enum v4l2_mpeg_video_h264_level</entry>
|
<entry>enum v4l2_mpeg_video_h264_level</entry>
|
||||||
</row>
|
</row>
|
||||||
@@ -1641,7 +1641,7 @@ Possible values are:</entry>
|
|||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
<row>
|
<row id="v4l2-mpeg-video-mpeg4-level">
|
||||||
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL</constant> </entry>
|
||||||
<entry>enum v4l2_mpeg_video_mpeg4_level</entry>
|
<entry>enum v4l2_mpeg_video_mpeg4_level</entry>
|
||||||
</row>
|
</row>
|
||||||
@@ -1689,9 +1689,9 @@ Possible values are:</entry>
|
|||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
<row>
|
<row id="v4l2-mpeg-video-h264-profile">
|
||||||
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_PROFILE</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_PROFILE</constant> </entry>
|
||||||
<entry>enum v4l2_mpeg_h264_profile</entry>
|
<entry>enum v4l2_mpeg_video_h264_profile</entry>
|
||||||
</row>
|
</row>
|
||||||
<row><entry spanname="descr">The profile information for H264.
|
<row><entry spanname="descr">The profile information for H264.
|
||||||
Applicable to the H264 encoder.
|
Applicable to the H264 encoder.
|
||||||
@@ -1774,9 +1774,9 @@ Possible values are:</entry>
|
|||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
<row>
|
<row id="v4l2-mpeg-video-mpeg4-profile">
|
||||||
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE</constant> </entry>
|
||||||
<entry>enum v4l2_mpeg_mpeg4_profile</entry>
|
<entry>enum v4l2_mpeg_video_mpeg4_profile</entry>
|
||||||
</row>
|
</row>
|
||||||
<row><entry spanname="descr">The profile information for MPEG4.
|
<row><entry spanname="descr">The profile information for MPEG4.
|
||||||
Applicable to the MPEG4 encoder.
|
Applicable to the MPEG4 encoder.
|
||||||
@@ -1820,9 +1820,9 @@ Applicable to the encoder.
|
|||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
<row>
|
<row id="v4l2-mpeg-video-multi-slice-mode">
|
||||||
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE</constant> </entry>
|
||||||
<entry>enum v4l2_mpeg_multi_slice_mode</entry>
|
<entry>enum v4l2_mpeg_video_multi_slice_mode</entry>
|
||||||
</row>
|
</row>
|
||||||
<row><entry spanname="descr">Determines how the encoder should handle division of frame into slices.
|
<row><entry spanname="descr">Determines how the encoder should handle division of frame into slices.
|
||||||
Applicable to the encoder.
|
Applicable to the encoder.
|
||||||
@@ -1868,9 +1868,9 @@ Applicable to the encoder.</entry>
|
|||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
<row>
|
<row id="v4l2-mpeg-video-h264-loop-filter-mode">
|
||||||
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE</constant> </entry>
|
||||||
<entry>enum v4l2_mpeg_h264_loop_filter_mode</entry>
|
<entry>enum v4l2_mpeg_video_h264_loop_filter_mode</entry>
|
||||||
</row>
|
</row>
|
||||||
<row><entry spanname="descr">Loop filter mode for H264 encoder.
|
<row><entry spanname="descr">Loop filter mode for H264 encoder.
|
||||||
Possible values are:</entry>
|
Possible values are:</entry>
|
||||||
@@ -1913,9 +1913,9 @@ Applicable to the H264 encoder.</entry>
|
|||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
<row>
|
<row id="v4l2-mpeg-video-h264-entropy-mode">
|
||||||
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE</constant> </entry>
|
||||||
<entry>enum v4l2_mpeg_h264_symbol_mode</entry>
|
<entry>enum v4l2_mpeg_video_h264_entropy_mode</entry>
|
||||||
</row>
|
</row>
|
||||||
<row><entry spanname="descr">Entropy coding mode for H264 - CABAC/CAVALC.
|
<row><entry spanname="descr">Entropy coding mode for H264 - CABAC/CAVALC.
|
||||||
Applicable to the H264 encoder.
|
Applicable to the H264 encoder.
|
||||||
@@ -2140,9 +2140,9 @@ previous frames. Applicable to the H264 encoder.</entry>
|
|||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
<row>
|
<row id="v4l2-mpeg-video-header-mode">
|
||||||
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_HEADER_MODE</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_HEADER_MODE</constant> </entry>
|
||||||
<entry>enum v4l2_mpeg_header_mode</entry>
|
<entry>enum v4l2_mpeg_video_header_mode</entry>
|
||||||
</row>
|
</row>
|
||||||
<row><entry spanname="descr">Determines whether the header is returned as the first buffer or is
|
<row><entry spanname="descr">Determines whether the header is returned as the first buffer or is
|
||||||
it returned together with the first frame. Applicable to encoders.
|
it returned together with the first frame. Applicable to encoders.
|
||||||
@@ -2320,9 +2320,9 @@ Valid only when H.264 and macroblock level RC is enabled (<constant>V4L2_CID_MPE
|
|||||||
Applicable to the H264 encoder.</entry>
|
Applicable to the H264 encoder.</entry>
|
||||||
</row>
|
</row>
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
<row>
|
<row id="v4l2-mpeg-mfc51-video-frame-skip-mode">
|
||||||
<entry spanname="id"><constant>V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE</constant> </entry>
|
||||||
<entry>enum v4l2_mpeg_mfc51_frame_skip_mode</entry>
|
<entry>enum v4l2_mpeg_mfc51_video_frame_skip_mode</entry>
|
||||||
</row>
|
</row>
|
||||||
<row><entry spanname="descr">
|
<row><entry spanname="descr">
|
||||||
Indicates in what conditions the encoder should skip frames. If encoding a frame would cause the encoded stream to be larger then
|
Indicates in what conditions the encoder should skip frames. If encoding a frame would cause the encoded stream to be larger then
|
||||||
@@ -2361,9 +2361,9 @@ the stream will meet tight bandwidth contraints. Applicable to encoders.
|
|||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
<row><entry></entry></row>
|
<row><entry></entry></row>
|
||||||
<row>
|
<row id="v4l2-mpeg-mfc51-video-force-frame-type">
|
||||||
<entry spanname="id"><constant>V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE</constant> </entry>
|
<entry spanname="id"><constant>V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE</constant> </entry>
|
||||||
<entry>enum v4l2_mpeg_mfc51_force_frame_type</entry>
|
<entry>enum v4l2_mpeg_mfc51_video_force_frame_type</entry>
|
||||||
</row>
|
</row>
|
||||||
<row><entry spanname="descr">Force a frame type for the next queued buffer. Applicable to encoders.
|
<row><entry spanname="descr">Force a frame type for the next queued buffer. Applicable to encoders.
|
||||||
Possible values are:</entry>
|
Possible values are:</entry>
|
||||||
|
|||||||
@@ -62,6 +62,13 @@ can be safely used to identify the chip. You will have to instantiate
|
|||||||
the devices explicitly. Please see Documentation/i2c/instantiating-devices for
|
the devices explicitly. Please see Documentation/i2c/instantiating-devices for
|
||||||
details.
|
details.
|
||||||
|
|
||||||
|
WARNING: Do not access chip registers using the i2cdump command, and do not use
|
||||||
|
any of the i2ctools commands on a command register (0xa5 to 0xac). The chips
|
||||||
|
supported by this driver interpret any access to a command register (including
|
||||||
|
read commands) as request to execute the command in question. This may result in
|
||||||
|
power loss, board resets, and/or Flash corruption. Worst case, your board may
|
||||||
|
turn into a brick.
|
||||||
|
|
||||||
|
|
||||||
Sysfs entries
|
Sysfs entries
|
||||||
-------------
|
-------------
|
||||||
|
|||||||
@@ -319,4 +319,6 @@ Code Seq#(hex) Include File Comments
|
|||||||
<mailto:thomas@winischhofer.net>
|
<mailto:thomas@winischhofer.net>
|
||||||
0xF4 00-1F video/mbxfb.h mbxfb
|
0xF4 00-1F video/mbxfb.h mbxfb
|
||||||
<mailto:raph@8d.com>
|
<mailto:raph@8d.com>
|
||||||
|
0xF6 all LTTng Linux Trace Toolkit Next Generation
|
||||||
|
<mailto:mathieu.desnoyers@efficios.com>
|
||||||
0xFD all linux/dm-ioctl.h
|
0xFD all linux/dm-ioctl.h
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
|||||||
VERSION = 3
|
VERSION = 3
|
||||||
PATCHLEVEL = 1
|
PATCHLEVEL = 1
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 0
|
||||||
EXTRAVERSION = -rc5
|
EXTRAVERSION = -rc6
|
||||||
NAME = "Divemaster Edition"
|
NAME = "Divemaster Edition"
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
|||||||
@@ -45,8 +45,13 @@
|
|||||||
#define L2X0_CLEAN_INV_LINE_PA 0x7F0
|
#define L2X0_CLEAN_INV_LINE_PA 0x7F0
|
||||||
#define L2X0_CLEAN_INV_LINE_IDX 0x7F8
|
#define L2X0_CLEAN_INV_LINE_IDX 0x7F8
|
||||||
#define L2X0_CLEAN_INV_WAY 0x7FC
|
#define L2X0_CLEAN_INV_WAY 0x7FC
|
||||||
#define L2X0_LOCKDOWN_WAY_D 0x900
|
/*
|
||||||
#define L2X0_LOCKDOWN_WAY_I 0x904
|
* The lockdown registers repeat 8 times for L310, the L210 has only one
|
||||||
|
* D and one I lockdown register at 0x0900 and 0x0904.
|
||||||
|
*/
|
||||||
|
#define L2X0_LOCKDOWN_WAY_D_BASE 0x900
|
||||||
|
#define L2X0_LOCKDOWN_WAY_I_BASE 0x904
|
||||||
|
#define L2X0_LOCKDOWN_STRIDE 0x08
|
||||||
#define L2X0_TEST_OPERATION 0xF00
|
#define L2X0_TEST_OPERATION 0xF00
|
||||||
#define L2X0_LINE_DATA 0xF10
|
#define L2X0_LINE_DATA 0xF10
|
||||||
#define L2X0_LINE_TAG 0xF30
|
#define L2X0_LINE_TAG 0xF30
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
|
||||||
#include <asm/hardware/entry-macro-gic.S>
|
#include <asm/hardware/entry-macro-gic.S>
|
||||||
|
|
||||||
.macro disable_fiq
|
.macro disable_fiq
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <asm/proc-fns.h>
|
#include <asm/proc-fns.h>
|
||||||
#include <mach/hardware.h>
|
|
||||||
|
|
||||||
static inline void arch_idle(void)
|
static inline void arch_idle(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
#include <mach/hardware.h>
|
|
||||||
#include <mach/cns3xxx.h>
|
#include <mach/cns3xxx.h>
|
||||||
|
|
||||||
#define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00))
|
#define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00))
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ static struct cns3xxx_pcie *sysdata_to_cnspci(void *sysdata)
|
|||||||
return &cns3xxx_pcie[root->domain];
|
return &cns3xxx_pcie[root->domain];
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct cns3xxx_pcie *pdev_to_cnspci(struct pci_dev *dev)
|
static struct cns3xxx_pcie *pdev_to_cnspci(const struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
return sysdata_to_cnspci(dev->sysdata);
|
return sysdata_to_cnspci(dev->sysdata);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,32 @@ static struct spi_board_info da850evm_spi_info[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTD
|
||||||
|
static void da850_evm_m25p80_notify_add(struct mtd_info *mtd)
|
||||||
|
{
|
||||||
|
char *mac_addr = davinci_soc_info.emac_pdata->mac_addr;
|
||||||
|
size_t retlen;
|
||||||
|
|
||||||
|
if (!strcmp(mtd->name, "MAC-Address")) {
|
||||||
|
mtd->read(mtd, 0, ETH_ALEN, &retlen, mac_addr);
|
||||||
|
if (retlen == ETH_ALEN)
|
||||||
|
pr_info("Read MAC addr from SPI Flash: %pM\n",
|
||||||
|
mac_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mtd_notifier da850evm_spi_notifier = {
|
||||||
|
.add = da850_evm_m25p80_notify_add,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void da850_evm_setup_mac_addr(void)
|
||||||
|
{
|
||||||
|
register_mtd_user(&da850evm_spi_notifier);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void da850_evm_setup_mac_addr(void) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct mtd_partition da850_evm_norflash_partition[] = {
|
static struct mtd_partition da850_evm_norflash_partition[] = {
|
||||||
{
|
{
|
||||||
.name = "bootloaders + env",
|
.name = "bootloaders + env",
|
||||||
@@ -1244,6 +1270,8 @@ static __init void da850_evm_init(void)
|
|||||||
if (ret)
|
if (ret)
|
||||||
pr_warning("da850_evm_init: sata registration failed: %d\n",
|
pr_warning("da850_evm_init: sata registration failed: %d\n",
|
||||||
ret);
|
ret);
|
||||||
|
|
||||||
|
da850_evm_setup_mac_addr();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
#ifdef CONFIG_SERIAL_8250_CONSOLE
|
||||||
|
|||||||
@@ -243,7 +243,7 @@
|
|||||||
#define PSC_STATE_DISABLE 2
|
#define PSC_STATE_DISABLE 2
|
||||||
#define PSC_STATE_ENABLE 3
|
#define PSC_STATE_ENABLE 3
|
||||||
|
|
||||||
#define MDSTAT_STATE_MASK 0x1f
|
#define MDSTAT_STATE_MASK 0x3f
|
||||||
#define MDCTL_FORCE BIT(31)
|
#define MDCTL_FORCE BIT(31)
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
|
|||||||
@@ -217,7 +217,11 @@ ddr2clk_stop_done:
|
|||||||
ENDPROC(davinci_ddr_psc_config)
|
ENDPROC(davinci_ddr_psc_config)
|
||||||
|
|
||||||
CACHE_FLUSH:
|
CACHE_FLUSH:
|
||||||
|
#ifdef CONFIG_CPU_V6
|
||||||
|
.word v6_flush_kern_cache_all
|
||||||
|
#else
|
||||||
.word arm926_flush_kern_cache_all
|
.word arm926_flush_kern_cache_all
|
||||||
|
#endif
|
||||||
|
|
||||||
ENTRY(davinci_cpu_suspend_sz)
|
ENTRY(davinci_cpu_suspend_sz)
|
||||||
.word . - davinci_cpu_suspend
|
.word . - davinci_cpu_suspend
|
||||||
|
|||||||
@@ -337,15 +337,15 @@ static unsigned long timer_reload;
|
|||||||
static void integrator_clocksource_init(u32 khz)
|
static void integrator_clocksource_init(u32 khz)
|
||||||
{
|
{
|
||||||
void __iomem *base = (void __iomem *)TIMER2_VA_BASE;
|
void __iomem *base = (void __iomem *)TIMER2_VA_BASE;
|
||||||
u32 ctrl = TIMER_CTRL_ENABLE;
|
u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
|
||||||
|
|
||||||
if (khz >= 1500) {
|
if (khz >= 1500) {
|
||||||
khz /= 16;
|
khz /= 16;
|
||||||
ctrl = TIMER_CTRL_DIV16;
|
ctrl |= TIMER_CTRL_DIV16;
|
||||||
}
|
}
|
||||||
|
|
||||||
writel(ctrl, base + TIMER_CTRL);
|
|
||||||
writel(0xffff, base + TIMER_LOAD);
|
writel(0xffff, base + TIMER_LOAD);
|
||||||
|
writel(ctrl, base + TIMER_CTRL);
|
||||||
|
|
||||||
clocksource_mmio_init(base + TIMER_VALUE, "timer2",
|
clocksource_mmio_init(base + TIMER_VALUE, "timer2",
|
||||||
khz * 1000, 200, 16, clocksource_mmio_readl_down);
|
khz * 1000, 200, 16, clocksource_mmio_readl_down);
|
||||||
|
|||||||
@@ -3078,6 +3078,7 @@ static struct clk gpt12_fck = {
|
|||||||
.name = "gpt12_fck",
|
.name = "gpt12_fck",
|
||||||
.ops = &clkops_null,
|
.ops = &clkops_null,
|
||||||
.parent = &secure_32k_fck,
|
.parent = &secure_32k_fck,
|
||||||
|
.clkdm_name = "wkup_clkdm",
|
||||||
.recalc = &followparent_recalc,
|
.recalc = &followparent_recalc,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3085,6 +3086,7 @@ static struct clk wdt1_fck = {
|
|||||||
.name = "wdt1_fck",
|
.name = "wdt1_fck",
|
||||||
.ops = &clkops_null,
|
.ops = &clkops_null,
|
||||||
.parent = &secure_32k_fck,
|
.parent = &secure_32k_fck,
|
||||||
|
.clkdm_name = "wkup_clkdm",
|
||||||
.recalc = &followparent_recalc,
|
.recalc = &followparent_recalc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3376,10 +3376,18 @@ int __init omap4xxx_clk_init(void)
|
|||||||
} else if (cpu_is_omap446x()) {
|
} else if (cpu_is_omap446x()) {
|
||||||
cpu_mask = RATE_IN_4460;
|
cpu_mask = RATE_IN_4460;
|
||||||
cpu_clkflg = CK_446X;
|
cpu_clkflg = CK_446X;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
clk_init(&omap2_clk_functions);
|
clk_init(&omap2_clk_functions);
|
||||||
omap2_clk_disable_clkdm_control();
|
|
||||||
|
/*
|
||||||
|
* Must stay commented until all OMAP SoC drivers are
|
||||||
|
* converted to runtime PM, or drivers may start crashing
|
||||||
|
*
|
||||||
|
* omap2_clk_disable_clkdm_control();
|
||||||
|
*/
|
||||||
|
|
||||||
for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks);
|
for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks);
|
||||||
c++)
|
c++)
|
||||||
|
|||||||
@@ -747,6 +747,7 @@ int clkdm_wakeup(struct clockdomain *clkdm)
|
|||||||
spin_lock_irqsave(&clkdm->lock, flags);
|
spin_lock_irqsave(&clkdm->lock, flags);
|
||||||
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
|
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
|
||||||
ret = arch_clkdm->clkdm_wakeup(clkdm);
|
ret = arch_clkdm->clkdm_wakeup(clkdm);
|
||||||
|
ret |= pwrdm_state_switch(clkdm->pwrdm.ptr);
|
||||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -818,6 +819,7 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
|
|||||||
spin_lock_irqsave(&clkdm->lock, flags);
|
spin_lock_irqsave(&clkdm->lock, flags);
|
||||||
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
|
clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;
|
||||||
arch_clkdm->clkdm_deny_idle(clkdm);
|
arch_clkdm->clkdm_deny_idle(clkdm);
|
||||||
|
pwrdm_state_switch(clkdm->pwrdm.ptr);
|
||||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ static struct omap_hwmod_addr_space omap2430_usbhsotg_addrs[] = {
|
|||||||
.pa_end = OMAP243X_HS_BASE + SZ_4K - 1,
|
.pa_end = OMAP243X_HS_BASE + SZ_4K - 1,
|
||||||
.flags = ADDR_TYPE_RT
|
.flags = ADDR_TYPE_RT
|
||||||
},
|
},
|
||||||
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* l4_core ->usbhsotg interface */
|
/* l4_core ->usbhsotg interface */
|
||||||
|
|||||||
@@ -130,7 +130,6 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
|
|||||||
} else {
|
} else {
|
||||||
hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
|
hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
|
||||||
clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
|
clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
|
||||||
pwrdm_wait_transition(pwrdm);
|
|
||||||
sleep_switch = FORCEWAKEUP_SWITCH;
|
sleep_switch = FORCEWAKEUP_SWITCH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,7 +155,6 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
pwrdm_wait_transition(pwrdm);
|
|
||||||
pwrdm_state_switch(pwrdm);
|
pwrdm_state_switch(pwrdm);
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -195,28 +195,35 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* pwrdm_init - set up the powerdomain layer
|
* pwrdm_init - set up the powerdomain layer
|
||||||
* @pwrdm_list: array of struct powerdomain pointers to register
|
* @pwrdms: array of struct powerdomain pointers to register
|
||||||
* @custom_funcs: func pointers for arch specific implementations
|
* @custom_funcs: func pointers for arch specific implementations
|
||||||
*
|
*
|
||||||
* Loop through the array of powerdomains @pwrdm_list, registering all
|
* Loop through the array of powerdomains @pwrdms, registering all
|
||||||
* that are available on the current CPU. If pwrdm_list is supplied
|
* that are available on the current CPU. Also, program all
|
||||||
* and not null, all of the referenced powerdomains will be
|
* powerdomain target state as ON; this is to prevent domains from
|
||||||
* registered. No return value. XXX pwrdm_list is not really a
|
* hitting low power states (if bootloader has target states set to
|
||||||
* "list"; it is an array. Rename appropriately.
|
* something other than ON) and potentially even losing context while
|
||||||
|
* PM is not fully initialized. The PM late init code can then program
|
||||||
|
* the desired target state for all the power domains. No return
|
||||||
|
* value.
|
||||||
*/
|
*/
|
||||||
void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs)
|
void pwrdm_init(struct powerdomain **pwrdms, struct pwrdm_ops *custom_funcs)
|
||||||
{
|
{
|
||||||
struct powerdomain **p = NULL;
|
struct powerdomain **p = NULL;
|
||||||
|
struct powerdomain *temp_p;
|
||||||
|
|
||||||
if (!custom_funcs)
|
if (!custom_funcs)
|
||||||
WARN(1, "powerdomain: No custom pwrdm functions registered\n");
|
WARN(1, "powerdomain: No custom pwrdm functions registered\n");
|
||||||
else
|
else
|
||||||
arch_pwrdm = custom_funcs;
|
arch_pwrdm = custom_funcs;
|
||||||
|
|
||||||
if (pwrdm_list) {
|
if (pwrdms) {
|
||||||
for (p = pwrdm_list; *p; p++)
|
for (p = pwrdms; *p; p++)
|
||||||
_pwrdm_register(*p);
|
_pwrdm_register(*p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(temp_p, &pwrdm_list, node)
|
||||||
|
pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -481,6 +481,7 @@ static void __init sirfsoc_clk_init(void)
|
|||||||
|
|
||||||
static struct of_device_id clkc_ids[] = {
|
static struct of_device_id clkc_ids[] = {
|
||||||
{ .compatible = "sirf,prima2-clkc" },
|
{ .compatible = "sirf,prima2-clkc" },
|
||||||
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init sirfsoc_of_clk_init(void)
|
void __init sirfsoc_of_clk_init(void)
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ static __init void sirfsoc_irq_init(void)
|
|||||||
|
|
||||||
static struct of_device_id intc_ids[] = {
|
static struct of_device_id intc_ids[] = {
|
||||||
{ .compatible = "sirf,prima2-intc" },
|
{ .compatible = "sirf,prima2-intc" },
|
||||||
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init sirfsoc_of_irq_init(void)
|
void __init sirfsoc_of_irq_init(void)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ static DEFINE_MUTEX(rstc_lock);
|
|||||||
|
|
||||||
static struct of_device_id rstc_ids[] = {
|
static struct of_device_id rstc_ids[] = {
|
||||||
{ .compatible = "sirf,prima2-rstc" },
|
{ .compatible = "sirf,prima2-rstc" },
|
||||||
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init sirfsoc_of_rstc_init(void)
|
static int __init sirfsoc_of_rstc_init(void)
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ static void __init sirfsoc_timer_init(void)
|
|||||||
|
|
||||||
static struct of_device_id timer_ids[] = {
|
static struct of_device_id timer_ids[] = {
|
||||||
{ .compatible = "sirf,prima2-tick" },
|
{ .compatible = "sirf,prima2-tick" },
|
||||||
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __init sirfsoc_of_timer_map(void)
|
static void __init sirfsoc_of_timer_map(void)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
cmp \tmp, # 0x5600 @ Is it ldrsb?
|
cmp \tmp, # 0x5600 @ Is it ldrsb?
|
||||||
orreq \tmp, \tmp, #1 << 11 @ Set L-bit if yes
|
orreq \tmp, \tmp, #1 << 11 @ Set L-bit if yes
|
||||||
tst \tmp, #1 << 11 @ L = 0 -> write
|
tst \tmp, #1 << 11 @ L = 0 -> write
|
||||||
orreq \psr, \psr, #1 << 11 @ yes.
|
orreq \fsr, \fsr, #1 << 11 @ yes.
|
||||||
b do_DataAbort
|
b do_DataAbort
|
||||||
not_thumb:
|
not_thumb:
|
||||||
.endm
|
.endm
|
||||||
|
|||||||
@@ -277,6 +277,25 @@ static void l2x0_disable(void)
|
|||||||
spin_unlock_irqrestore(&l2x0_lock, flags);
|
spin_unlock_irqrestore(&l2x0_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init l2x0_unlock(__u32 cache_id)
|
||||||
|
{
|
||||||
|
int lockregs;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (cache_id == L2X0_CACHE_ID_PART_L310)
|
||||||
|
lockregs = 8;
|
||||||
|
else
|
||||||
|
/* L210 and unknown types */
|
||||||
|
lockregs = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < lockregs; i++) {
|
||||||
|
writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
|
||||||
|
i * L2X0_LOCKDOWN_STRIDE);
|
||||||
|
writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE +
|
||||||
|
i * L2X0_LOCKDOWN_STRIDE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
|
void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
|
||||||
{
|
{
|
||||||
__u32 aux;
|
__u32 aux;
|
||||||
@@ -328,6 +347,8 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
|
|||||||
* accessing the below registers will fault.
|
* accessing the below registers will fault.
|
||||||
*/
|
*/
|
||||||
if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
|
if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
|
||||||
|
/* Make sure that I&D is not locked down when starting */
|
||||||
|
l2x0_unlock(cache_id);
|
||||||
|
|
||||||
/* l2x0 controller is disabled */
|
/* l2x0 controller is disabled */
|
||||||
writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
|
writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
|
|||||||
#ifdef CONFIG_HAVE_ARCH_PFN_VALID
|
#ifdef CONFIG_HAVE_ARCH_PFN_VALID
|
||||||
int pfn_valid(unsigned long pfn)
|
int pfn_valid(unsigned long pfn)
|
||||||
{
|
{
|
||||||
return memblock_is_memory(pfn << PAGE_SHIFT);
|
return memblock_is_memory(__pfn_to_phys(pfn));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pfn_valid);
|
EXPORT_SYMBOL(pfn_valid);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -615,6 +615,9 @@ static int _od_resume_noirq(struct device *dev)
|
|||||||
|
|
||||||
return pm_generic_resume_noirq(dev);
|
return pm_generic_resume_noirq(dev);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#define _od_suspend_noirq NULL
|
||||||
|
#define _od_resume_noirq NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct dev_pm_domain omap_device_pm_domain = {
|
static struct dev_pm_domain omap_device_pm_domain = {
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
|
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
|
||||||
|
|
||||||
int dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
|
|
||||||
|
|
||||||
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
||||||
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
|
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
|
||||||
@@ -47,6 +46,12 @@ dma_addr_t or1k_map_page(struct device *dev, struct page *page,
|
|||||||
void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
|
void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
|
||||||
size_t size, enum dma_data_direction dir,
|
size_t size, enum dma_data_direction dir,
|
||||||
struct dma_attrs *attrs);
|
struct dma_attrs *attrs);
|
||||||
|
int or1k_map_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir,
|
||||||
|
struct dma_attrs *attrs);
|
||||||
|
void or1k_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir,
|
||||||
|
struct dma_attrs *attrs);
|
||||||
void or1k_sync_single_for_cpu(struct device *dev,
|
void or1k_sync_single_for_cpu(struct device *dev,
|
||||||
dma_addr_t dma_handle, size_t size,
|
dma_addr_t dma_handle, size_t size,
|
||||||
enum dma_data_direction dir);
|
enum dma_data_direction dir);
|
||||||
@@ -98,6 +103,51 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
|
|||||||
debug_dma_unmap_page(dev, addr, size, dir, true);
|
debug_dma_unmap_page(dev, addr, size, dir, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
int i, ents;
|
||||||
|
struct scatterlist *s;
|
||||||
|
|
||||||
|
for_each_sg(sg, s, nents, i)
|
||||||
|
kmemcheck_mark_initialized(sg_virt(s), s->length);
|
||||||
|
BUG_ON(!valid_dma_direction(dir));
|
||||||
|
ents = or1k_map_sg(dev, sg, nents, dir, NULL);
|
||||||
|
debug_dma_map_sg(dev, sg, nents, ents, dir);
|
||||||
|
|
||||||
|
return ents;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
BUG_ON(!valid_dma_direction(dir));
|
||||||
|
debug_dma_unmap_sg(dev, sg, nents, dir);
|
||||||
|
or1k_unmap_sg(dev, sg, nents, dir, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
|
||||||
|
size_t offset, size_t size,
|
||||||
|
enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
dma_addr_t addr;
|
||||||
|
|
||||||
|
kmemcheck_mark_initialized(page_address(page) + offset, size);
|
||||||
|
BUG_ON(!valid_dma_direction(dir));
|
||||||
|
addr = or1k_map_page(dev, page, offset, size, dir, NULL);
|
||||||
|
debug_dma_map_page(dev, page, offset, size, dir, addr, false);
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
|
||||||
|
size_t size, enum dma_data_direction dir)
|
||||||
|
{
|
||||||
|
BUG_ON(!valid_dma_direction(dir));
|
||||||
|
or1k_unmap_page(dev, addr, size, dir, NULL);
|
||||||
|
debug_dma_unmap_page(dev, addr, size, dir, true);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
|
static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
|
||||||
size_t size,
|
size_t size,
|
||||||
enum dma_data_direction dir)
|
enum dma_data_direction dir)
|
||||||
@@ -119,7 +169,12 @@ static inline void dma_sync_single_for_device(struct device *dev,
|
|||||||
static inline int dma_supported(struct device *dev, u64 dma_mask)
|
static inline int dma_supported(struct device *dev, u64 dma_mask)
|
||||||
{
|
{
|
||||||
/* Support 32 bit DMA mask exclusively */
|
/* Support 32 bit DMA mask exclusively */
|
||||||
return dma_mask == 0xffffffffULL;
|
return dma_mask == DMA_BIT_MASK(32);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
|
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
|
||||||
|
|||||||
@@ -23,16 +23,11 @@
|
|||||||
|
|
||||||
/* This struct is saved by setup_frame in signal.c, to keep the current
|
/* This struct is saved by setup_frame in signal.c, to keep the current
|
||||||
context while a signal handler is executed. It's restored by sys_sigreturn.
|
context while a signal handler is executed. It's restored by sys_sigreturn.
|
||||||
|
|
||||||
To keep things simple, we use pt_regs here even though normally you just
|
|
||||||
specify the list of regs to save. Then we can use copy_from_user on the
|
|
||||||
entire regs instead of a bunch of get_user's as well...
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct sigcontext {
|
struct sigcontext {
|
||||||
struct pt_regs regs; /* needs to be first */
|
struct user_regs_struct regs; /* needs to be first */
|
||||||
unsigned long oldmask;
|
unsigned long oldmask;
|
||||||
unsigned long usp; /* usp before stacking this gunk on it */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ASM_OPENRISC_SIGCONTEXT_H */
|
#endif /* __ASM_OPENRISC_SIGCONTEXT_H */
|
||||||
|
|||||||
@@ -154,6 +154,33 @@ void or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
|
|||||||
/* Nothing special to do here... */
|
/* Nothing special to do here... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int or1k_map_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir,
|
||||||
|
struct dma_attrs *attrs)
|
||||||
|
{
|
||||||
|
struct scatterlist *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for_each_sg(sg, s, nents, i) {
|
||||||
|
s->dma_address = or1k_map_page(dev, sg_page(s), s->offset,
|
||||||
|
s->length, dir, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nents;
|
||||||
|
}
|
||||||
|
|
||||||
|
void or1k_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents, enum dma_data_direction dir,
|
||||||
|
struct dma_attrs *attrs)
|
||||||
|
{
|
||||||
|
struct scatterlist *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for_each_sg(sg, s, nents, i) {
|
||||||
|
or1k_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void or1k_sync_single_for_cpu(struct device *dev,
|
void or1k_sync_single_for_cpu(struct device *dev,
|
||||||
dma_addr_t dma_handle, size_t size,
|
dma_addr_t dma_handle, size_t size,
|
||||||
enum dma_data_direction dir)
|
enum dma_data_direction dir)
|
||||||
@@ -187,5 +214,4 @@ static int __init dma_init(void)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_initcall(dma_init);
|
fs_initcall(dma_init);
|
||||||
|
|||||||
@@ -52,31 +52,25 @@ struct rt_sigframe {
|
|||||||
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
|
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
|
||||||
{
|
{
|
||||||
unsigned int err = 0;
|
unsigned int err = 0;
|
||||||
unsigned long old_usp;
|
|
||||||
|
|
||||||
/* Alwys make any pending restarted system call return -EINTR */
|
/* Alwys make any pending restarted system call return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
||||||
|
|
||||||
/* restore the regs from &sc->regs (same as sc, since regs is first)
|
/*
|
||||||
|
* Restore the regs from &sc->regs.
|
||||||
* (sc is already checked for VERIFY_READ since the sigframe was
|
* (sc is already checked for VERIFY_READ since the sigframe was
|
||||||
* checked in sys_sigreturn previously)
|
* checked in sys_sigreturn previously)
|
||||||
*/
|
*/
|
||||||
|
if (__copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long)))
|
||||||
if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
|
goto badframe;
|
||||||
|
if (__copy_from_user(®s->pc, &sc->regs.pc, sizeof(unsigned long)))
|
||||||
|
goto badframe;
|
||||||
|
if (__copy_from_user(®s->sr, &sc->regs.sr, sizeof(unsigned long)))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
||||||
/* make sure the SM-bit is cleared so user-mode cannot fool us */
|
/* make sure the SM-bit is cleared so user-mode cannot fool us */
|
||||||
regs->sr &= ~SPR_SR_SM;
|
regs->sr &= ~SPR_SR_SM;
|
||||||
|
|
||||||
/* restore the old USP as it was before we stacked the sc etc.
|
|
||||||
* (we cannot just pop the sigcontext since we aligned the sp and
|
|
||||||
* stuff after pushing it)
|
|
||||||
*/
|
|
||||||
|
|
||||||
err |= __get_user(old_usp, &sc->usp);
|
|
||||||
|
|
||||||
regs->sp = old_usp;
|
|
||||||
|
|
||||||
/* TODO: the other ports use regs->orig_XX to disable syscall checks
|
/* TODO: the other ports use regs->orig_XX to disable syscall checks
|
||||||
* after this completes, but we don't use that mechanism. maybe we can
|
* after this completes, but we don't use that mechanism. maybe we can
|
||||||
* use it now ?
|
* use it now ?
|
||||||
@@ -137,18 +131,17 @@ static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
|
|||||||
unsigned long mask)
|
unsigned long mask)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
unsigned long usp = regs->sp;
|
|
||||||
|
|
||||||
/* copy the regs. they are first in sc so we can use sc directly */
|
/* copy the regs */
|
||||||
|
|
||||||
err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
|
err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long));
|
||||||
|
err |= __copy_to_user(&sc->regs.pc, ®s->pc, sizeof(unsigned long));
|
||||||
|
err |= __copy_to_user(&sc->regs.sr, ®s->sr, sizeof(unsigned long));
|
||||||
|
|
||||||
/* then some other stuff */
|
/* then some other stuff */
|
||||||
|
|
||||||
err |= __put_user(mask, &sc->oldmask);
|
err |= __put_user(mask, &sc->oldmask);
|
||||||
|
|
||||||
err |= __put_user(usp, &sc->usp);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift)
|
|||||||
: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
|
: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
|
||||||
#elif defined(__x86_64__)
|
#elif defined(__x86_64__)
|
||||||
__asm__ (
|
__asm__ (
|
||||||
"mul %[mul_frac] ; shrd $32, %[hi], %[lo]"
|
"mulq %[mul_frac] ; shrd $32, %[hi], %[lo]"
|
||||||
: [lo]"=a"(product),
|
: [lo]"=a"(product),
|
||||||
[hi]"=d"(tmp)
|
[hi]"=d"(tmp)
|
||||||
: "0"(delta),
|
: "0"(delta),
|
||||||
|
|||||||
@@ -1900,6 +1900,9 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
|
|||||||
|
|
||||||
perf_callchain_store(entry, regs->ip);
|
perf_callchain_store(entry, regs->ip);
|
||||||
|
|
||||||
|
if (!current->mm)
|
||||||
|
return;
|
||||||
|
|
||||||
if (perf_callchain_user32(regs, entry))
|
if (perf_callchain_user32(regs, entry))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -365,8 +365,13 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
|
|||||||
*/
|
*/
|
||||||
if (bus) {
|
if (bus) {
|
||||||
struct pci_bus *child;
|
struct pci_bus *child;
|
||||||
list_for_each_entry(child, &bus->children, node)
|
list_for_each_entry(child, &bus->children, node) {
|
||||||
pcie_bus_configure_settings(child, child->self->pcie_mpss);
|
struct pci_dev *self = child->self;
|
||||||
|
if (!self)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pcie_bus_configure_settings(child, self->pcie_mpss);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bus)
|
if (!bus)
|
||||||
|
|||||||
@@ -184,6 +184,19 @@ static unsigned long __init xen_set_identity(const struct e820entry *list,
|
|||||||
PFN_UP(start_pci), PFN_DOWN(last));
|
PFN_UP(start_pci), PFN_DOWN(last));
|
||||||
return identity;
|
return identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long __init xen_get_max_pages(void)
|
||||||
|
{
|
||||||
|
unsigned long max_pages = MAX_DOMAIN_PAGES;
|
||||||
|
domid_t domid = DOMID_SELF;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = HYPERVISOR_memory_op(XENMEM_maximum_reservation, &domid);
|
||||||
|
if (ret > 0)
|
||||||
|
max_pages = ret;
|
||||||
|
return min(max_pages, MAX_DOMAIN_PAGES);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* machine_specific_memory_setup - Hook for machine specific memory setup.
|
* machine_specific_memory_setup - Hook for machine specific memory setup.
|
||||||
**/
|
**/
|
||||||
@@ -292,6 +305,12 @@ char * __init xen_memory_setup(void)
|
|||||||
|
|
||||||
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
|
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
|
||||||
|
|
||||||
|
extra_limit = xen_get_max_pages();
|
||||||
|
if (extra_limit >= max_pfn)
|
||||||
|
extra_pages = extra_limit - max_pfn;
|
||||||
|
else
|
||||||
|
extra_pages = 0;
|
||||||
|
|
||||||
extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820);
|
extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <xen/page.h>
|
#include <xen/page.h>
|
||||||
#include <xen/events.h>
|
#include <xen/events.h>
|
||||||
|
|
||||||
|
#include <xen/hvc-console.h>
|
||||||
#include "xen-ops.h"
|
#include "xen-ops.h"
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
|
|
||||||
@@ -207,6 +208,15 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
|
|||||||
unsigned cpu;
|
unsigned cpu;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
if (skip_ioapic_setup) {
|
||||||
|
char *m = (max_cpus == 0) ?
|
||||||
|
"The nosmp parameter is incompatible with Xen; " \
|
||||||
|
"use Xen dom0_max_vcpus=1 parameter" :
|
||||||
|
"The noapic parameter is incompatible with Xen";
|
||||||
|
|
||||||
|
xen_raw_printk(m);
|
||||||
|
panic(m);
|
||||||
|
}
|
||||||
xen_init_lock_cpu(0);
|
xen_init_lock_cpu(0);
|
||||||
|
|
||||||
smp_store_cpu_info(0);
|
smp_store_cpu_info(0);
|
||||||
|
|||||||
@@ -113,11 +113,13 @@ xen_iret_start_crit:
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's something pending, mask events again so we can
|
* If there's something pending, mask events again so we can
|
||||||
* jump back into xen_hypervisor_callback
|
* jump back into xen_hypervisor_callback. Otherwise do not
|
||||||
|
* touch XEN_vcpu_info_mask.
|
||||||
*/
|
*/
|
||||||
sete XEN_vcpu_info_mask(%eax)
|
jne 1f
|
||||||
|
movb $1, XEN_vcpu_info_mask(%eax)
|
||||||
|
|
||||||
popl %eax
|
1: popl %eax
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* From this point on the registers are restored and the stack
|
* From this point on the registers are restored and the stack
|
||||||
|
|||||||
@@ -168,13 +168,11 @@ struct regmap *regmap_init(struct device *dev,
|
|||||||
map->work_buf = kmalloc(map->format.buf_size, GFP_KERNEL);
|
map->work_buf = kmalloc(map->format.buf_size, GFP_KERNEL);
|
||||||
if (map->work_buf == NULL) {
|
if (map->work_buf == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err_bus;
|
goto err_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
|
|
||||||
err_bus:
|
|
||||||
module_put(map->bus->owner);
|
|
||||||
err_map:
|
err_map:
|
||||||
kfree(map);
|
kfree(map);
|
||||||
err:
|
err:
|
||||||
@@ -188,7 +186,6 @@ EXPORT_SYMBOL_GPL(regmap_init);
|
|||||||
void regmap_exit(struct regmap *map)
|
void regmap_exit(struct regmap *map)
|
||||||
{
|
{
|
||||||
kfree(map->work_buf);
|
kfree(map->work_buf);
|
||||||
module_put(map->bus->owner);
|
|
||||||
kfree(map);
|
kfree(map);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(regmap_exit);
|
EXPORT_SYMBOL_GPL(regmap_exit);
|
||||||
|
|||||||
@@ -174,8 +174,10 @@ struct d40_base;
|
|||||||
* @tasklet: Tasklet that gets scheduled from interrupt context to complete a
|
* @tasklet: Tasklet that gets scheduled from interrupt context to complete a
|
||||||
* transfer and call client callback.
|
* transfer and call client callback.
|
||||||
* @client: Cliented owned descriptor list.
|
* @client: Cliented owned descriptor list.
|
||||||
|
* @pending_queue: Submitted jobs, to be issued by issue_pending()
|
||||||
* @active: Active descriptor.
|
* @active: Active descriptor.
|
||||||
* @queue: Queued jobs.
|
* @queue: Queued jobs.
|
||||||
|
* @prepare_queue: Prepared jobs.
|
||||||
* @dma_cfg: The client configuration of this dma channel.
|
* @dma_cfg: The client configuration of this dma channel.
|
||||||
* @configured: whether the dma_cfg configuration is valid
|
* @configured: whether the dma_cfg configuration is valid
|
||||||
* @base: Pointer to the device instance struct.
|
* @base: Pointer to the device instance struct.
|
||||||
@@ -203,6 +205,7 @@ struct d40_chan {
|
|||||||
struct list_head pending_queue;
|
struct list_head pending_queue;
|
||||||
struct list_head active;
|
struct list_head active;
|
||||||
struct list_head queue;
|
struct list_head queue;
|
||||||
|
struct list_head prepare_queue;
|
||||||
struct stedma40_chan_cfg dma_cfg;
|
struct stedma40_chan_cfg dma_cfg;
|
||||||
bool configured;
|
bool configured;
|
||||||
struct d40_base *base;
|
struct d40_base *base;
|
||||||
@@ -477,7 +480,6 @@ static struct d40_desc *d40_desc_get(struct d40_chan *d40c)
|
|||||||
|
|
||||||
list_for_each_entry_safe(d, _d, &d40c->client, node)
|
list_for_each_entry_safe(d, _d, &d40c->client, node)
|
||||||
if (async_tx_test_ack(&d->txd)) {
|
if (async_tx_test_ack(&d->txd)) {
|
||||||
d40_pool_lli_free(d40c, d);
|
|
||||||
d40_desc_remove(d);
|
d40_desc_remove(d);
|
||||||
desc = d;
|
desc = d;
|
||||||
memset(desc, 0, sizeof(*desc));
|
memset(desc, 0, sizeof(*desc));
|
||||||
@@ -644,8 +646,11 @@ static struct d40_desc *d40_first_active_get(struct d40_chan *d40c)
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* remove desc from current queue and add it to the pending_queue */
|
||||||
static void d40_desc_queue(struct d40_chan *d40c, struct d40_desc *desc)
|
static void d40_desc_queue(struct d40_chan *d40c, struct d40_desc *desc)
|
||||||
{
|
{
|
||||||
|
d40_desc_remove(desc);
|
||||||
|
desc->is_in_client_list = false;
|
||||||
list_add_tail(&desc->node, &d40c->pending_queue);
|
list_add_tail(&desc->node, &d40c->pending_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,6 +808,7 @@ done:
|
|||||||
static void d40_term_all(struct d40_chan *d40c)
|
static void d40_term_all(struct d40_chan *d40c)
|
||||||
{
|
{
|
||||||
struct d40_desc *d40d;
|
struct d40_desc *d40d;
|
||||||
|
struct d40_desc *_d;
|
||||||
|
|
||||||
/* Release active descriptors */
|
/* Release active descriptors */
|
||||||
while ((d40d = d40_first_active_get(d40c))) {
|
while ((d40d = d40_first_active_get(d40c))) {
|
||||||
@@ -822,6 +828,21 @@ static void d40_term_all(struct d40_chan *d40c)
|
|||||||
d40_desc_free(d40c, d40d);
|
d40_desc_free(d40c, d40d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release client owned descriptors */
|
||||||
|
if (!list_empty(&d40c->client))
|
||||||
|
list_for_each_entry_safe(d40d, _d, &d40c->client, node) {
|
||||||
|
d40_desc_remove(d40d);
|
||||||
|
d40_desc_free(d40c, d40d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release descriptors in prepare queue */
|
||||||
|
if (!list_empty(&d40c->prepare_queue))
|
||||||
|
list_for_each_entry_safe(d40d, _d,
|
||||||
|
&d40c->prepare_queue, node) {
|
||||||
|
d40_desc_remove(d40d);
|
||||||
|
d40_desc_free(d40c, d40d);
|
||||||
|
}
|
||||||
|
|
||||||
d40c->pending_tx = 0;
|
d40c->pending_tx = 0;
|
||||||
d40c->busy = false;
|
d40c->busy = false;
|
||||||
}
|
}
|
||||||
@@ -1208,7 +1229,6 @@ static void dma_tasklet(unsigned long data)
|
|||||||
|
|
||||||
if (!d40d->cyclic) {
|
if (!d40d->cyclic) {
|
||||||
if (async_tx_test_ack(&d40d->txd)) {
|
if (async_tx_test_ack(&d40d->txd)) {
|
||||||
d40_pool_lli_free(d40c, d40d);
|
|
||||||
d40_desc_remove(d40d);
|
d40_desc_remove(d40d);
|
||||||
d40_desc_free(d40c, d40d);
|
d40_desc_free(d40c, d40d);
|
||||||
} else {
|
} else {
|
||||||
@@ -1595,21 +1615,10 @@ static int d40_free_dma(struct d40_chan *d40c)
|
|||||||
u32 event;
|
u32 event;
|
||||||
struct d40_phy_res *phy = d40c->phy_chan;
|
struct d40_phy_res *phy = d40c->phy_chan;
|
||||||
bool is_src;
|
bool is_src;
|
||||||
struct d40_desc *d;
|
|
||||||
struct d40_desc *_d;
|
|
||||||
|
|
||||||
|
|
||||||
/* Terminate all queued and active transfers */
|
/* Terminate all queued and active transfers */
|
||||||
d40_term_all(d40c);
|
d40_term_all(d40c);
|
||||||
|
|
||||||
/* Release client owned descriptors */
|
|
||||||
if (!list_empty(&d40c->client))
|
|
||||||
list_for_each_entry_safe(d, _d, &d40c->client, node) {
|
|
||||||
d40_pool_lli_free(d40c, d);
|
|
||||||
d40_desc_remove(d);
|
|
||||||
d40_desc_free(d40c, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (phy == NULL) {
|
if (phy == NULL) {
|
||||||
chan_err(d40c, "phy == null\n");
|
chan_err(d40c, "phy == null\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -1911,6 +1920,12 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add descriptor to the prepare queue in order to be able
|
||||||
|
* to free them later in terminate_all
|
||||||
|
*/
|
||||||
|
list_add_tail(&desc->node, &chan->prepare_queue);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&chan->lock, flags);
|
spin_unlock_irqrestore(&chan->lock, flags);
|
||||||
|
|
||||||
return &desc->txd;
|
return &desc->txd;
|
||||||
@@ -2400,6 +2415,7 @@ static void __init d40_chan_init(struct d40_base *base, struct dma_device *dma,
|
|||||||
INIT_LIST_HEAD(&d40c->queue);
|
INIT_LIST_HEAD(&d40c->queue);
|
||||||
INIT_LIST_HEAD(&d40c->pending_queue);
|
INIT_LIST_HEAD(&d40c->pending_queue);
|
||||||
INIT_LIST_HEAD(&d40c->client);
|
INIT_LIST_HEAD(&d40c->client);
|
||||||
|
INIT_LIST_HEAD(&d40c->prepare_queue);
|
||||||
|
|
||||||
tasklet_init(&d40c->tasklet, dma_tasklet,
|
tasklet_init(&d40c->tasklet, dma_tasklet,
|
||||||
(unsigned long) d40c);
|
(unsigned long) d40c);
|
||||||
|
|||||||
@@ -256,7 +256,6 @@ int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed,
|
|||||||
{
|
{
|
||||||
printk(KERN_ERR "panic occurred, switching back to text console\n");
|
printk(KERN_ERR "panic occurred, switching back to text console\n");
|
||||||
return drm_fb_helper_force_kernel_mode();
|
return drm_fb_helper_force_kernel_mode();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_fb_helper_panic);
|
EXPORT_SYMBOL(drm_fb_helper_panic);
|
||||||
|
|
||||||
|
|||||||
@@ -530,7 +530,8 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
|
|||||||
nouveau_gpuobj_ref(NULL, &obj);
|
nouveau_gpuobj_ref(NULL, &obj);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else
|
||||||
|
if (USE_SEMA(dev)) {
|
||||||
/* map fence bo into channel's vm */
|
/* map fence bo into channel's vm */
|
||||||
ret = nouveau_bo_vma_add(dev_priv->fence.bo, chan->vm,
|
ret = nouveau_bo_vma_add(dev_priv->fence.bo, chan->vm,
|
||||||
&chan->fence.vma);
|
&chan->fence.vma);
|
||||||
|
|||||||
@@ -37,8 +37,11 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
nvbe->ttm_alloced = kmalloc(sizeof(bool) * num_pages, GFP_KERNEL);
|
nvbe->ttm_alloced = kmalloc(sizeof(bool) * num_pages, GFP_KERNEL);
|
||||||
if (!nvbe->ttm_alloced)
|
if (!nvbe->ttm_alloced) {
|
||||||
|
kfree(nvbe->pages);
|
||||||
|
nvbe->pages = NULL;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
nvbe->nr_pages = 0;
|
nvbe->nr_pages = 0;
|
||||||
while (num_pages--) {
|
while (num_pages--) {
|
||||||
@@ -126,7 +129,7 @@ nv04_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
|
|||||||
|
|
||||||
for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) {
|
for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) {
|
||||||
nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3);
|
nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3);
|
||||||
dma_offset += NV_CTXDMA_PAGE_SIZE;
|
offset_l += NV_CTXDMA_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -781,11 +781,20 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
|
|||||||
struct drm_device *dev = crtc->dev;
|
struct drm_device *dev = crtc->dev;
|
||||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||||
struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
|
struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index];
|
||||||
struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
|
struct drm_framebuffer *drm_fb;
|
||||||
struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
|
struct nouveau_framebuffer *fb;
|
||||||
int arb_burst, arb_lwm;
|
int arb_burst, arb_lwm;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
|
||||||
|
|
||||||
|
/* no fb bound */
|
||||||
|
if (!atomic && !crtc->fb) {
|
||||||
|
NV_DEBUG_KMS(dev, "No FB bound\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* If atomic, we want to switch to the fb we were passed, so
|
/* If atomic, we want to switch to the fb we were passed, so
|
||||||
* now we update pointers to do that. (We don't pin; just
|
* now we update pointers to do that. (We don't pin; just
|
||||||
* assume we're already pinned and update the base address.)
|
* assume we're already pinned and update the base address.)
|
||||||
@@ -794,6 +803,8 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
|
|||||||
drm_fb = passed_fb;
|
drm_fb = passed_fb;
|
||||||
fb = nouveau_framebuffer(passed_fb);
|
fb = nouveau_framebuffer(passed_fb);
|
||||||
} else {
|
} else {
|
||||||
|
drm_fb = crtc->fb;
|
||||||
|
fb = nouveau_framebuffer(crtc->fb);
|
||||||
/* If not atomic, we can go ahead and pin, and unpin the
|
/* If not atomic, we can go ahead and pin, and unpin the
|
||||||
* old fb we were passed.
|
* old fb we were passed.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -519,12 +519,18 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
|
|||||||
struct drm_device *dev = nv_crtc->base.dev;
|
struct drm_device *dev = nv_crtc->base.dev;
|
||||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||||
struct nouveau_channel *evo = nv50_display(dev)->master;
|
struct nouveau_channel *evo = nv50_display(dev)->master;
|
||||||
struct drm_framebuffer *drm_fb = nv_crtc->base.fb;
|
struct drm_framebuffer *drm_fb;
|
||||||
struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
|
struct nouveau_framebuffer *fb;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
|
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
|
||||||
|
|
||||||
|
/* no fb bound */
|
||||||
|
if (!atomic && !crtc->fb) {
|
||||||
|
NV_DEBUG_KMS(dev, "No FB bound\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* If atomic, we want to switch to the fb we were passed, so
|
/* If atomic, we want to switch to the fb we were passed, so
|
||||||
* now we update pointers to do that. (We don't pin; just
|
* now we update pointers to do that. (We don't pin; just
|
||||||
* assume we're already pinned and update the base address.)
|
* assume we're already pinned and update the base address.)
|
||||||
@@ -533,6 +539,8 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
|
|||||||
drm_fb = passed_fb;
|
drm_fb = passed_fb;
|
||||||
fb = nouveau_framebuffer(passed_fb);
|
fb = nouveau_framebuffer(passed_fb);
|
||||||
} else {
|
} else {
|
||||||
|
drm_fb = crtc->fb;
|
||||||
|
fb = nouveau_framebuffer(crtc->fb);
|
||||||
/* If not atomic, we can go ahead and pin, and unpin the
|
/* If not atomic, we can go ahead and pin, and unpin the
|
||||||
* old fb we were passed.
|
* old fb we were passed.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1297,12 +1297,33 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
|
|||||||
if (!radeon_dig_connector->edp_on)
|
if (!radeon_dig_connector->edp_on)
|
||||||
atombios_set_edp_panel_power(connector,
|
atombios_set_edp_panel_power(connector,
|
||||||
ATOM_TRANSMITTER_ACTION_POWER_OFF);
|
ATOM_TRANSMITTER_ACTION_POWER_OFF);
|
||||||
} else {
|
} else if (radeon_connector_encoder_is_dp_bridge(connector)) {
|
||||||
|
/* DP bridges are always DP */
|
||||||
|
radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
|
||||||
|
/* get the DPCD from the bridge */
|
||||||
|
radeon_dp_getdpcd(radeon_connector);
|
||||||
|
|
||||||
|
if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
|
||||||
|
ret = connector_status_connected;
|
||||||
|
else {
|
||||||
/* need to setup ddc on the bridge */
|
/* need to setup ddc on the bridge */
|
||||||
if (radeon_connector_encoder_is_dp_bridge(connector)) {
|
|
||||||
if (encoder)
|
if (encoder)
|
||||||
radeon_atom_ext_encoder_setup_ddc(encoder);
|
radeon_atom_ext_encoder_setup_ddc(encoder);
|
||||||
|
if (radeon_ddc_probe(radeon_connector,
|
||||||
|
radeon_connector->requires_extended_probe))
|
||||||
|
ret = connector_status_connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ret == connector_status_disconnected) &&
|
||||||
|
radeon_connector->dac_load_detect) {
|
||||||
|
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
|
||||||
|
struct drm_encoder_helper_funcs *encoder_funcs;
|
||||||
|
if (encoder) {
|
||||||
|
encoder_funcs = encoder->helper_private;
|
||||||
|
ret = encoder_funcs->detect(encoder, connector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
|
radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
|
||||||
if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
|
if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
|
||||||
ret = connector_status_connected;
|
ret = connector_status_connected;
|
||||||
@@ -1318,16 +1339,6 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
|
|||||||
ret = connector_status_connected;
|
ret = connector_status_connected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret == connector_status_disconnected) &&
|
|
||||||
radeon_connector->dac_load_detect) {
|
|
||||||
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
|
|
||||||
struct drm_encoder_helper_funcs *encoder_funcs;
|
|
||||||
if (encoder) {
|
|
||||||
encoder_funcs = encoder->helper_private;
|
|
||||||
ret = encoder_funcs->detect(encoder, connector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
radeon_connector_update_scratch_regs(connector, ret);
|
radeon_connector_update_scratch_regs(connector, ret);
|
||||||
|
|||||||
@@ -707,16 +707,21 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
|
|||||||
radeon_router_select_ddc_port(radeon_connector);
|
radeon_router_select_ddc_port(radeon_connector);
|
||||||
|
|
||||||
if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
|
if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
|
||||||
(radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
|
(radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) ||
|
||||||
|
radeon_connector_encoder_is_dp_bridge(&radeon_connector->base)) {
|
||||||
struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
|
struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
|
||||||
|
|
||||||
if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
|
if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
|
||||||
dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus)
|
dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus)
|
||||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter);
|
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
|
||||||
}
|
&dig->dp_i2c_bus->adapter);
|
||||||
if (!radeon_connector->ddc_bus)
|
else if (radeon_connector->ddc_bus && !radeon_connector->edid)
|
||||||
return -1;
|
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
|
||||||
if (!radeon_connector->edid) {
|
&radeon_connector->ddc_bus->adapter);
|
||||||
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
|
} else {
|
||||||
|
if (radeon_connector->ddc_bus && !radeon_connector->edid)
|
||||||
|
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
|
||||||
|
&radeon_connector->ddc_bus->adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!radeon_connector->edid) {
|
if (!radeon_connector->edid) {
|
||||||
|
|||||||
@@ -277,6 +277,7 @@
|
|||||||
#define USB_DEVICE_ID_PENPOWER 0x00f4
|
#define USB_DEVICE_ID_PENPOWER 0x00f4
|
||||||
|
|
||||||
#define USB_VENDOR_ID_GREENASIA 0x0e8f
|
#define USB_VENDOR_ID_GREENASIA 0x0e8f
|
||||||
|
#define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013
|
||||||
|
|
||||||
#define USB_VENDOR_ID_GRETAGMACBETH 0x0971
|
#define USB_VENDOR_ID_GRETAGMACBETH 0x0971
|
||||||
#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005
|
#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005
|
||||||
|
|||||||
@@ -81,6 +81,28 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
|
|||||||
#define NO_TOUCHES -1
|
#define NO_TOUCHES -1
|
||||||
#define SINGLE_TOUCH_UP -2
|
#define SINGLE_TOUCH_UP -2
|
||||||
|
|
||||||
|
/* Touch surface information. Dimension is in hundredths of a mm, min and max
|
||||||
|
* are in units. */
|
||||||
|
#define MOUSE_DIMENSION_X (float)9056
|
||||||
|
#define MOUSE_MIN_X -1100
|
||||||
|
#define MOUSE_MAX_X 1258
|
||||||
|
#define MOUSE_RES_X ((MOUSE_MAX_X - MOUSE_MIN_X) / (MOUSE_DIMENSION_X / 100))
|
||||||
|
#define MOUSE_DIMENSION_Y (float)5152
|
||||||
|
#define MOUSE_MIN_Y -1589
|
||||||
|
#define MOUSE_MAX_Y 2047
|
||||||
|
#define MOUSE_RES_Y ((MOUSE_MAX_Y - MOUSE_MIN_Y) / (MOUSE_DIMENSION_Y / 100))
|
||||||
|
|
||||||
|
#define TRACKPAD_DIMENSION_X (float)13000
|
||||||
|
#define TRACKPAD_MIN_X -2909
|
||||||
|
#define TRACKPAD_MAX_X 3167
|
||||||
|
#define TRACKPAD_RES_X \
|
||||||
|
((TRACKPAD_MAX_X - TRACKPAD_MIN_X) / (TRACKPAD_DIMENSION_X / 100))
|
||||||
|
#define TRACKPAD_DIMENSION_Y (float)11000
|
||||||
|
#define TRACKPAD_MIN_Y -2456
|
||||||
|
#define TRACKPAD_MAX_Y 2565
|
||||||
|
#define TRACKPAD_RES_Y \
|
||||||
|
((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct magicmouse_sc - Tracks Magic Mouse-specific data.
|
* struct magicmouse_sc - Tracks Magic Mouse-specific data.
|
||||||
* @input: Input device through which we report events.
|
* @input: Input device through which we report events.
|
||||||
@@ -406,17 +428,31 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
|
|||||||
* inverse of the reported Y.
|
* inverse of the reported Y.
|
||||||
*/
|
*/
|
||||||
if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
|
if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
|
||||||
input_set_abs_params(input, ABS_MT_POSITION_X, -1100,
|
input_set_abs_params(input, ABS_MT_POSITION_X,
|
||||||
1358, 4, 0);
|
MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
|
||||||
input_set_abs_params(input, ABS_MT_POSITION_Y, -1589,
|
input_set_abs_params(input, ABS_MT_POSITION_Y,
|
||||||
2047, 4, 0);
|
MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
|
||||||
|
|
||||||
|
input_abs_set_res(input, ABS_MT_POSITION_X,
|
||||||
|
MOUSE_RES_X);
|
||||||
|
input_abs_set_res(input, ABS_MT_POSITION_Y,
|
||||||
|
MOUSE_RES_Y);
|
||||||
} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
|
} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
|
||||||
input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0);
|
input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
|
||||||
input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0);
|
TRACKPAD_MAX_X, 4, 0);
|
||||||
input_set_abs_params(input, ABS_MT_POSITION_X, -2909,
|
input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
|
||||||
3167, 4, 0);
|
TRACKPAD_MAX_Y, 4, 0);
|
||||||
input_set_abs_params(input, ABS_MT_POSITION_Y, -2456,
|
input_set_abs_params(input, ABS_MT_POSITION_X,
|
||||||
2565, 4, 0);
|
TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
|
||||||
|
input_set_abs_params(input, ABS_MT_POSITION_Y,
|
||||||
|
TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
|
||||||
|
|
||||||
|
input_abs_set_res(input, ABS_X, TRACKPAD_RES_X);
|
||||||
|
input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y);
|
||||||
|
input_abs_set_res(input, ABS_MT_POSITION_X,
|
||||||
|
TRACKPAD_RES_X);
|
||||||
|
input_abs_set_res(input, ABS_MT_POSITION_Y,
|
||||||
|
TRACKPAD_RES_Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
input_set_events_per_packet(input, 60);
|
input_set_events_per_packet(input, 60);
|
||||||
@@ -501,9 +537,17 @@ static int magicmouse_probe(struct hid_device *hdev,
|
|||||||
}
|
}
|
||||||
report->size = 6;
|
report->size = 6;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some devices repond with 'invalid report id' when feature
|
||||||
|
* report switching it into multitouch mode is sent to it.
|
||||||
|
*
|
||||||
|
* This results in -EIO from the _raw low-level transport callback,
|
||||||
|
* but there seems to be no other way of switching the mode.
|
||||||
|
* Thus the super-ugly hacky success check below.
|
||||||
|
*/
|
||||||
ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
|
ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
|
||||||
HID_FEATURE_REPORT);
|
HID_FEATURE_REPORT);
|
||||||
if (ret != sizeof(feature)) {
|
if (ret != -EIO && ret != sizeof(feature)) {
|
||||||
hid_err(hdev, "unable to request touch data (%d)\n", ret);
|
hid_err(hdev, "unable to request touch data (%d)\n", ret);
|
||||||
goto err_stop_hw;
|
goto err_stop_hw;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -353,11 +353,7 @@ static int wacom_probe(struct hid_device *hdev,
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n",
|
hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n",
|
||||||
ret);
|
ret);
|
||||||
/*
|
goto err_battery;
|
||||||
* battery attribute is not critical for the tablet, but if it
|
|
||||||
* failed then there is no need to create ac attribute
|
|
||||||
*/
|
|
||||||
goto move_on;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wdata->ac.properties = wacom_ac_props;
|
wdata->ac.properties = wacom_ac_props;
|
||||||
@@ -371,14 +367,8 @@ static int wacom_probe(struct hid_device *hdev,
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
hid_warn(hdev,
|
hid_warn(hdev,
|
||||||
"can't create ac battery attribute, err: %d\n", ret);
|
"can't create ac battery attribute, err: %d\n", ret);
|
||||||
/*
|
goto err_ac;
|
||||||
* ac attribute is not critical for the tablet, but if it
|
|
||||||
* failed then we don't want to battery attribute to exist
|
|
||||||
*/
|
|
||||||
power_supply_unregister(&wdata->battery);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
move_on:
|
|
||||||
#endif
|
#endif
|
||||||
hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
|
hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
|
||||||
input = hidinput->input;
|
input = hidinput->input;
|
||||||
@@ -416,6 +406,13 @@ move_on:
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
|
||||||
|
err_ac:
|
||||||
|
power_supply_unregister(&wdata->battery);
|
||||||
|
err_battery:
|
||||||
|
device_remove_file(&hdev->dev, &dev_attr_speed);
|
||||||
|
hid_hw_stop(hdev);
|
||||||
|
#endif
|
||||||
err_free:
|
err_free:
|
||||||
kfree(wdata);
|
kfree(wdata);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -426,6 +423,7 @@ static void wacom_remove(struct hid_device *hdev)
|
|||||||
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
|
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
|
||||||
struct wacom_data *wdata = hid_get_drvdata(hdev);
|
struct wacom_data *wdata = hid_get_drvdata(hdev);
|
||||||
#endif
|
#endif
|
||||||
|
device_remove_file(&hdev->dev, &dev_attr_speed);
|
||||||
hid_hw_stop(hdev);
|
hid_hw_stop(hdev);
|
||||||
|
|
||||||
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
|
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ static const struct hid_blacklist {
|
|||||||
{ USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
|
{ USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
|
||||||
|
|
||||||
{ USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT },
|
{ USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT },
|
||||||
|
{ USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT },
|
||||||
{ USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
|
{ USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
|
||||||
{ USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
|
{ USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
|
||||||
{ USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT },
|
{ USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT },
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ static inline int MV_TO_LIMIT(int mv, int range)
|
|||||||
|
|
||||||
static inline int ADC_TO_CURR(int adc, int gain)
|
static inline int ADC_TO_CURR(int adc, int gain)
|
||||||
{
|
{
|
||||||
return adc * 1400000 / gain * 255;
|
return adc * 1400000 / (gain * 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -141,13 +141,11 @@ static int ucd9000_probe(struct i2c_client *client,
|
|||||||
block_buffer[ret] = '\0';
|
block_buffer[ret] = '\0';
|
||||||
dev_info(&client->dev, "Device ID %s\n", block_buffer);
|
dev_info(&client->dev, "Device ID %s\n", block_buffer);
|
||||||
|
|
||||||
mid = NULL;
|
for (mid = ucd9000_id; mid->name[0]; mid++) {
|
||||||
for (i = 0; i < ARRAY_SIZE(ucd9000_id); i++) {
|
|
||||||
mid = &ucd9000_id[i];
|
|
||||||
if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
|
if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!mid || !strlen(mid->name)) {
|
if (!mid->name[0]) {
|
||||||
dev_err(&client->dev, "Unsupported device\n");
|
dev_err(&client->dev, "Unsupported device\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,13 +68,11 @@ static int ucd9200_probe(struct i2c_client *client,
|
|||||||
block_buffer[ret] = '\0';
|
block_buffer[ret] = '\0';
|
||||||
dev_info(&client->dev, "Device ID %s\n", block_buffer);
|
dev_info(&client->dev, "Device ID %s\n", block_buffer);
|
||||||
|
|
||||||
mid = NULL;
|
for (mid = ucd9200_id; mid->name[0]; mid++) {
|
||||||
for (i = 0; i < ARRAY_SIZE(ucd9200_id); i++) {
|
|
||||||
mid = &ucd9200_id[i];
|
|
||||||
if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
|
if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!mid || !strlen(mid->name)) {
|
if (!mid->name[0]) {
|
||||||
dev_err(&client->dev, "Unsupported device\n");
|
dev_err(&client->dev, "Unsupported device\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,12 +109,15 @@ static int __devinit ce4100_i2c_probe(struct pci_dev *dev,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
sds = kzalloc(sizeof(*sds), GFP_KERNEL);
|
sds = kzalloc(sizeof(*sds), GFP_KERNEL);
|
||||||
if (!sds)
|
if (!sds) {
|
||||||
|
ret = -ENOMEM;
|
||||||
goto err_mem;
|
goto err_mem;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) {
|
for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) {
|
||||||
sds->pdev[i] = add_i2c_device(dev, i);
|
sds->pdev[i] = add_i2c_device(dev, i);
|
||||||
if (IS_ERR(sds->pdev[i])) {
|
if (IS_ERR(sds->pdev[i])) {
|
||||||
|
ret = PTR_ERR(sds->pdev[i]);
|
||||||
while (--i >= 0)
|
while (--i >= 0)
|
||||||
platform_device_unregister(sds->pdev[i]);
|
platform_device_unregister(sds->pdev[i]);
|
||||||
goto err_dev_add;
|
goto err_dev_add;
|
||||||
|
|||||||
@@ -270,14 +270,30 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
|
|||||||
|
|
||||||
/* Rounds down to not include partial word at the end of buf */
|
/* Rounds down to not include partial word at the end of buf */
|
||||||
words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
|
words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
|
||||||
|
|
||||||
|
/* It's very common to have < 4 bytes, so optimize that case. */
|
||||||
|
if (words_to_transfer) {
|
||||||
if (words_to_transfer > tx_fifo_avail)
|
if (words_to_transfer > tx_fifo_avail)
|
||||||
words_to_transfer = tx_fifo_avail;
|
words_to_transfer = tx_fifo_avail;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update state before writing to FIFO. If this casues us
|
||||||
|
* to finish writing all bytes (AKA buf_remaining goes to 0) we
|
||||||
|
* have a potential for an interrupt (PACKET_XFER_COMPLETE is
|
||||||
|
* not maskable). We need to make sure that the isr sees
|
||||||
|
* buf_remaining as 0 and doesn't call us back re-entrantly.
|
||||||
|
*/
|
||||||
|
buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
|
||||||
|
tx_fifo_avail -= words_to_transfer;
|
||||||
|
i2c_dev->msg_buf_remaining = buf_remaining;
|
||||||
|
i2c_dev->msg_buf = buf +
|
||||||
|
words_to_transfer * BYTES_PER_FIFO_WORD;
|
||||||
|
barrier();
|
||||||
|
|
||||||
i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
|
i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
|
||||||
|
|
||||||
buf += words_to_transfer * BYTES_PER_FIFO_WORD;
|
buf += words_to_transfer * BYTES_PER_FIFO_WORD;
|
||||||
buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
|
}
|
||||||
tx_fifo_avail -= words_to_transfer;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is a partial word at the end of buf, handle it manually to
|
* If there is a partial word at the end of buf, handle it manually to
|
||||||
@@ -287,14 +303,15 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
|
|||||||
if (tx_fifo_avail > 0 && buf_remaining > 0) {
|
if (tx_fifo_avail > 0 && buf_remaining > 0) {
|
||||||
BUG_ON(buf_remaining > 3);
|
BUG_ON(buf_remaining > 3);
|
||||||
memcpy(&val, buf, buf_remaining);
|
memcpy(&val, buf, buf_remaining);
|
||||||
|
|
||||||
|
/* Again update before writing to FIFO to make sure isr sees. */
|
||||||
|
i2c_dev->msg_buf_remaining = 0;
|
||||||
|
i2c_dev->msg_buf = NULL;
|
||||||
|
barrier();
|
||||||
|
|
||||||
i2c_writel(i2c_dev, val, I2C_TX_FIFO);
|
i2c_writel(i2c_dev, val, I2C_TX_FIFO);
|
||||||
buf_remaining = 0;
|
|
||||||
tx_fifo_avail--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BUG_ON(tx_fifo_avail > 0 && buf_remaining > 0);
|
|
||||||
i2c_dev->msg_buf_remaining = buf_remaining;
|
|
||||||
i2c_dev->msg_buf = buf;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,9 +428,10 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
|
|||||||
tegra_i2c_mask_irq(i2c_dev, I2C_INT_TX_FIFO_DATA_REQ);
|
tegra_i2c_mask_irq(i2c_dev, I2C_INT_TX_FIFO_DATA_REQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((status & I2C_INT_PACKET_XFER_COMPLETE) &&
|
if (status & I2C_INT_PACKET_XFER_COMPLETE) {
|
||||||
!i2c_dev->msg_buf_remaining)
|
BUG_ON(i2c_dev->msg_buf_remaining);
|
||||||
complete(&i2c_dev->msg_complete);
|
complete(&i2c_dev->msg_complete);
|
||||||
|
}
|
||||||
|
|
||||||
i2c_writel(i2c_dev, status, I2C_INT_STATUS);
|
i2c_writel(i2c_dev, status, I2C_INT_STATUS);
|
||||||
if (i2c_dev->is_dvc)
|
if (i2c_dev->is_dvc)
|
||||||
@@ -531,7 +549,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
|
|||||||
|
|
||||||
static u32 tegra_i2c_func(struct i2c_adapter *adap)
|
static u32 tegra_i2c_func(struct i2c_adapter *adap)
|
||||||
{
|
{
|
||||||
return I2C_FUNC_I2C;
|
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct i2c_algorithm tegra_i2c_algo = {
|
static const struct i2c_algorithm tegra_i2c_algo = {
|
||||||
@@ -719,6 +737,17 @@ static int tegra_i2c_resume(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_OF)
|
||||||
|
/* Match table for of_platform binding */
|
||||||
|
static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
|
||||||
|
{ .compatible = "nvidia,tegra20-i2c", },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
|
||||||
|
#else
|
||||||
|
#define tegra_i2c_of_match NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct platform_driver tegra_i2c_driver = {
|
static struct platform_driver tegra_i2c_driver = {
|
||||||
.probe = tegra_i2c_probe,
|
.probe = tegra_i2c_probe,
|
||||||
.remove = tegra_i2c_remove,
|
.remove = tegra_i2c_remove,
|
||||||
@@ -729,6 +758,7 @@ static struct platform_driver tegra_i2c_driver = {
|
|||||||
.driver = {
|
.driver = {
|
||||||
.name = "tegra-i2c",
|
.name = "tegra-i2c",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = tegra_i2c_of_match,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -605,7 +605,9 @@ static void build_inv_all(struct iommu_cmd *cmd)
|
|||||||
* Writes the command to the IOMMUs command buffer and informs the
|
* Writes the command to the IOMMUs command buffer and informs the
|
||||||
* hardware about the new command.
|
* hardware about the new command.
|
||||||
*/
|
*/
|
||||||
static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
|
static int iommu_queue_command_sync(struct amd_iommu *iommu,
|
||||||
|
struct iommu_cmd *cmd,
|
||||||
|
bool sync)
|
||||||
{
|
{
|
||||||
u32 left, tail, head, next_tail;
|
u32 left, tail, head, next_tail;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@@ -639,13 +641,18 @@ again:
|
|||||||
copy_cmd_to_buffer(iommu, cmd, tail);
|
copy_cmd_to_buffer(iommu, cmd, tail);
|
||||||
|
|
||||||
/* We need to sync now to make sure all commands are processed */
|
/* We need to sync now to make sure all commands are processed */
|
||||||
iommu->need_sync = true;
|
iommu->need_sync = sync;
|
||||||
|
|
||||||
spin_unlock_irqrestore(&iommu->lock, flags);
|
spin_unlock_irqrestore(&iommu->lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
|
||||||
|
{
|
||||||
|
return iommu_queue_command_sync(iommu, cmd, true);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function queues a completion wait command into the command
|
* This function queues a completion wait command into the command
|
||||||
* buffer of an IOMMU
|
* buffer of an IOMMU
|
||||||
@@ -661,7 +668,7 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
|
|||||||
|
|
||||||
build_completion_wait(&cmd, (u64)&sem);
|
build_completion_wait(&cmd, (u64)&sem);
|
||||||
|
|
||||||
ret = iommu_queue_command(iommu, &cmd);
|
ret = iommu_queue_command_sync(iommu, &cmd, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -840,14 +847,9 @@ static void domain_flush_complete(struct protection_domain *domain)
|
|||||||
static void domain_flush_devices(struct protection_domain *domain)
|
static void domain_flush_devices(struct protection_domain *domain)
|
||||||
{
|
{
|
||||||
struct iommu_dev_data *dev_data;
|
struct iommu_dev_data *dev_data;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&domain->lock, flags);
|
|
||||||
|
|
||||||
list_for_each_entry(dev_data, &domain->dev_list, list)
|
list_for_each_entry(dev_data, &domain->dev_list, list)
|
||||||
device_flush_dte(dev_data);
|
device_flush_dte(dev_data);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&domain->lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -1138,8 +1138,11 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
rdev->sectors = rdev->sb_start;
|
rdev->sectors = rdev->sb_start;
|
||||||
|
/* Limit to 4TB as metadata cannot record more than that */
|
||||||
|
if (rdev->sectors >= (2ULL << 32))
|
||||||
|
rdev->sectors = (2ULL << 32) - 2;
|
||||||
|
|
||||||
if (rdev->sectors < sb->size * 2 && sb->level > 1)
|
if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1)
|
||||||
/* "this cannot possibly happen" ... */
|
/* "this cannot possibly happen" ... */
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
|
||||||
@@ -1173,7 +1176,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
|
|||||||
mddev->clevel[0] = 0;
|
mddev->clevel[0] = 0;
|
||||||
mddev->layout = sb->layout;
|
mddev->layout = sb->layout;
|
||||||
mddev->raid_disks = sb->raid_disks;
|
mddev->raid_disks = sb->raid_disks;
|
||||||
mddev->dev_sectors = sb->size * 2;
|
mddev->dev_sectors = ((sector_t)sb->size) * 2;
|
||||||
mddev->events = ev1;
|
mddev->events = ev1;
|
||||||
mddev->bitmap_info.offset = 0;
|
mddev->bitmap_info.offset = 0;
|
||||||
mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9;
|
mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9;
|
||||||
@@ -1415,6 +1418,11 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
|
|||||||
rdev->sb_start = calc_dev_sboffset(rdev);
|
rdev->sb_start = calc_dev_sboffset(rdev);
|
||||||
if (!num_sectors || num_sectors > rdev->sb_start)
|
if (!num_sectors || num_sectors > rdev->sb_start)
|
||||||
num_sectors = rdev->sb_start;
|
num_sectors = rdev->sb_start;
|
||||||
|
/* Limit to 4TB as metadata cannot record more than that.
|
||||||
|
* 4TB == 2^32 KB, or 2*2^32 sectors.
|
||||||
|
*/
|
||||||
|
if (num_sectors >= (2ULL << 32))
|
||||||
|
num_sectors = (2ULL << 32) - 2;
|
||||||
md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
|
md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
|
||||||
rdev->sb_page);
|
rdev->sb_page);
|
||||||
md_super_wait(rdev->mddev);
|
md_super_wait(rdev->mddev);
|
||||||
|
|||||||
@@ -1099,12 +1099,11 @@ read_again:
|
|||||||
bio_list_add(&conf->pending_bio_list, mbio);
|
bio_list_add(&conf->pending_bio_list, mbio);
|
||||||
spin_unlock_irqrestore(&conf->device_lock, flags);
|
spin_unlock_irqrestore(&conf->device_lock, flags);
|
||||||
}
|
}
|
||||||
r1_bio_write_done(r1_bio);
|
/* Mustn't call r1_bio_write_done before this next test,
|
||||||
|
* as it could result in the bio being freed.
|
||||||
/* In case raid1d snuck in to freeze_array */
|
*/
|
||||||
wake_up(&conf->wait_barrier);
|
|
||||||
|
|
||||||
if (sectors_handled < (bio->bi_size >> 9)) {
|
if (sectors_handled < (bio->bi_size >> 9)) {
|
||||||
|
r1_bio_write_done(r1_bio);
|
||||||
/* We need another r1_bio. It has already been counted
|
/* We need another r1_bio. It has already been counted
|
||||||
* in bio->bi_phys_segments
|
* in bio->bi_phys_segments
|
||||||
*/
|
*/
|
||||||
@@ -1117,6 +1116,11 @@ read_again:
|
|||||||
goto retry_write;
|
goto retry_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r1_bio_write_done(r1_bio);
|
||||||
|
|
||||||
|
/* In case raid1d snuck in to freeze_array */
|
||||||
|
wake_up(&conf->wait_barrier);
|
||||||
|
|
||||||
if (do_sync || !bitmap || !plugged)
|
if (do_sync || !bitmap || !plugged)
|
||||||
md_wakeup_thread(mddev->thread);
|
md_wakeup_thread(mddev->thread);
|
||||||
|
|
||||||
|
|||||||
@@ -337,6 +337,21 @@ static void close_write(r10bio_t *r10_bio)
|
|||||||
md_write_end(r10_bio->mddev);
|
md_write_end(r10_bio->mddev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void one_write_done(r10bio_t *r10_bio)
|
||||||
|
{
|
||||||
|
if (atomic_dec_and_test(&r10_bio->remaining)) {
|
||||||
|
if (test_bit(R10BIO_WriteError, &r10_bio->state))
|
||||||
|
reschedule_retry(r10_bio);
|
||||||
|
else {
|
||||||
|
close_write(r10_bio);
|
||||||
|
if (test_bit(R10BIO_MadeGood, &r10_bio->state))
|
||||||
|
reschedule_retry(r10_bio);
|
||||||
|
else
|
||||||
|
raid_end_bio_io(r10_bio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void raid10_end_write_request(struct bio *bio, int error)
|
static void raid10_end_write_request(struct bio *bio, int error)
|
||||||
{
|
{
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
||||||
@@ -387,17 +402,7 @@ static void raid10_end_write_request(struct bio *bio, int error)
|
|||||||
* Let's see if all mirrored write operations have finished
|
* Let's see if all mirrored write operations have finished
|
||||||
* already.
|
* already.
|
||||||
*/
|
*/
|
||||||
if (atomic_dec_and_test(&r10_bio->remaining)) {
|
one_write_done(r10_bio);
|
||||||
if (test_bit(R10BIO_WriteError, &r10_bio->state))
|
|
||||||
reschedule_retry(r10_bio);
|
|
||||||
else {
|
|
||||||
close_write(r10_bio);
|
|
||||||
if (test_bit(R10BIO_MadeGood, &r10_bio->state))
|
|
||||||
reschedule_retry(r10_bio);
|
|
||||||
else
|
|
||||||
raid_end_bio_io(r10_bio);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dec_rdev)
|
if (dec_rdev)
|
||||||
rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev);
|
rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev);
|
||||||
}
|
}
|
||||||
@@ -1127,20 +1132,12 @@ retry_write:
|
|||||||
spin_unlock_irqrestore(&conf->device_lock, flags);
|
spin_unlock_irqrestore(&conf->device_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atomic_dec_and_test(&r10_bio->remaining)) {
|
/* Don't remove the bias on 'remaining' (one_write_done) until
|
||||||
/* This matches the end of raid10_end_write_request() */
|
* after checking if we need to go around again.
|
||||||
bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector,
|
*/
|
||||||
r10_bio->sectors,
|
|
||||||
!test_bit(R10BIO_Degraded, &r10_bio->state),
|
|
||||||
0);
|
|
||||||
md_write_end(mddev);
|
|
||||||
raid_end_bio_io(r10_bio);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In case raid10d snuck in to freeze_array */
|
|
||||||
wake_up(&conf->wait_barrier);
|
|
||||||
|
|
||||||
if (sectors_handled < (bio->bi_size >> 9)) {
|
if (sectors_handled < (bio->bi_size >> 9)) {
|
||||||
|
one_write_done(r10_bio);
|
||||||
/* We need another r10_bio. It has already been counted
|
/* We need another r10_bio. It has already been counted
|
||||||
* in bio->bi_phys_segments.
|
* in bio->bi_phys_segments.
|
||||||
*/
|
*/
|
||||||
@@ -1154,6 +1151,10 @@ retry_write:
|
|||||||
r10_bio->state = 0;
|
r10_bio->state = 0;
|
||||||
goto retry_write;
|
goto retry_write;
|
||||||
}
|
}
|
||||||
|
one_write_done(r10_bio);
|
||||||
|
|
||||||
|
/* In case raid10d snuck in to freeze_array */
|
||||||
|
wake_up(&conf->wait_barrier);
|
||||||
|
|
||||||
if (do_sync || !mddev->bitmap || !plugged)
|
if (do_sync || !mddev->bitmap || !plugged)
|
||||||
md_wakeup_thread(mddev->thread);
|
md_wakeup_thread(mddev->thread);
|
||||||
|
|||||||
@@ -224,26 +224,8 @@ static struct dvb_usb_device_properties vp7045_properties;
|
|||||||
static int vp7045_usb_probe(struct usb_interface *intf,
|
static int vp7045_usb_probe(struct usb_interface *intf,
|
||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
struct dvb_usb_device *d;
|
return dvb_usb_device_init(intf, &vp7045_properties,
|
||||||
int ret = dvb_usb_device_init(intf, &vp7045_properties,
|
THIS_MODULE, NULL, adapter_nr);
|
||||||
THIS_MODULE, &d, adapter_nr);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
d->priv = kmalloc(20, GFP_KERNEL);
|
|
||||||
if (!d->priv) {
|
|
||||||
dvb_usb_device_exit(intf);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vp7045_usb_disconnect(struct usb_interface *intf)
|
|
||||||
{
|
|
||||||
struct dvb_usb_device *d = usb_get_intfdata(intf);
|
|
||||||
kfree(d->priv);
|
|
||||||
dvb_usb_device_exit(intf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct usb_device_id vp7045_usb_table [] = {
|
static struct usb_device_id vp7045_usb_table [] = {
|
||||||
@@ -258,7 +240,7 @@ MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
|
|||||||
static struct dvb_usb_device_properties vp7045_properties = {
|
static struct dvb_usb_device_properties vp7045_properties = {
|
||||||
.usb_ctrl = CYPRESS_FX2,
|
.usb_ctrl = CYPRESS_FX2,
|
||||||
.firmware = "dvb-usb-vp7045-01.fw",
|
.firmware = "dvb-usb-vp7045-01.fw",
|
||||||
.size_of_priv = sizeof(u8 *),
|
.size_of_priv = 20,
|
||||||
|
|
||||||
.num_adapters = 1,
|
.num_adapters = 1,
|
||||||
.adapter = {
|
.adapter = {
|
||||||
@@ -305,7 +287,7 @@ static struct dvb_usb_device_properties vp7045_properties = {
|
|||||||
static struct usb_driver vp7045_usb_driver = {
|
static struct usb_driver vp7045_usb_driver = {
|
||||||
.name = "dvb_usb_vp7045",
|
.name = "dvb_usb_vp7045",
|
||||||
.probe = vp7045_usb_probe,
|
.probe = vp7045_usb_probe,
|
||||||
.disconnect = vp7045_usb_disconnect,
|
.disconnect = dvb_usb_device_exit,
|
||||||
.id_table = vp7045_usb_table,
|
.id_table = vp7045_usb_table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -618,7 +618,6 @@ static void nvt_dump_rx_buf(struct nvt_dev *nvt)
|
|||||||
static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
|
static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
|
||||||
{
|
{
|
||||||
DEFINE_IR_RAW_EVENT(rawir);
|
DEFINE_IR_RAW_EVENT(rawir);
|
||||||
unsigned int count;
|
|
||||||
u32 carrier;
|
u32 carrier;
|
||||||
u8 sample;
|
u8 sample;
|
||||||
int i;
|
int i;
|
||||||
@@ -631,65 +630,38 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
|
|||||||
if (nvt->carrier_detect_enabled)
|
if (nvt->carrier_detect_enabled)
|
||||||
carrier = nvt_rx_carrier_detect(nvt);
|
carrier = nvt_rx_carrier_detect(nvt);
|
||||||
|
|
||||||
count = nvt->pkts;
|
nvt_dbg_verbose("Processing buffer of len %d", nvt->pkts);
|
||||||
nvt_dbg_verbose("Processing buffer of len %d", count);
|
|
||||||
|
|
||||||
init_ir_raw_event(&rawir);
|
init_ir_raw_event(&rawir);
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < nvt->pkts; i++) {
|
||||||
nvt->pkts--;
|
|
||||||
sample = nvt->buf[i];
|
sample = nvt->buf[i];
|
||||||
|
|
||||||
rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
|
rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
|
||||||
rawir.duration = US_TO_NS((sample & BUF_LEN_MASK)
|
rawir.duration = US_TO_NS((sample & BUF_LEN_MASK)
|
||||||
* SAMPLE_PERIOD);
|
* SAMPLE_PERIOD);
|
||||||
|
|
||||||
if ((sample & BUF_LEN_MASK) == BUF_LEN_MASK) {
|
|
||||||
if (nvt->rawir.pulse == rawir.pulse)
|
|
||||||
nvt->rawir.duration += rawir.duration;
|
|
||||||
else {
|
|
||||||
nvt->rawir.duration = rawir.duration;
|
|
||||||
nvt->rawir.pulse = rawir.pulse;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
rawir.duration += nvt->rawir.duration;
|
|
||||||
|
|
||||||
init_ir_raw_event(&nvt->rawir);
|
|
||||||
nvt->rawir.duration = 0;
|
|
||||||
nvt->rawir.pulse = rawir.pulse;
|
|
||||||
|
|
||||||
if (sample == BUF_PULSE_BIT)
|
|
||||||
rawir.pulse = false;
|
|
||||||
|
|
||||||
if (rawir.duration) {
|
|
||||||
nvt_dbg("Storing %s with duration %d",
|
nvt_dbg("Storing %s with duration %d",
|
||||||
rawir.pulse ? "pulse" : "space",
|
rawir.pulse ? "pulse" : "space", rawir.duration);
|
||||||
rawir.duration);
|
|
||||||
|
|
||||||
ir_raw_event_store_with_filter(nvt->rdev, &rawir);
|
ir_raw_event_store_with_filter(nvt->rdev, &rawir);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BUF_PULSE_BIT indicates end of IR data, BUF_REPEAT_BYTE
|
* BUF_PULSE_BIT indicates end of IR data, BUF_REPEAT_BYTE
|
||||||
* indicates end of IR signal, but new data incoming. In both
|
* indicates end of IR signal, but new data incoming. In both
|
||||||
* cases, it means we're ready to call ir_raw_event_handle
|
* cases, it means we're ready to call ir_raw_event_handle
|
||||||
*/
|
*/
|
||||||
if ((sample == BUF_PULSE_BIT) && nvt->pkts) {
|
if ((sample == BUF_PULSE_BIT) && (i + 1 < nvt->pkts)) {
|
||||||
nvt_dbg("Calling ir_raw_event_handle (signal end)\n");
|
nvt_dbg("Calling ir_raw_event_handle (signal end)\n");
|
||||||
ir_raw_event_handle(nvt->rdev);
|
ir_raw_event_handle(nvt->rdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvt->pkts = 0;
|
||||||
|
|
||||||
nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n");
|
nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n");
|
||||||
ir_raw_event_handle(nvt->rdev);
|
ir_raw_event_handle(nvt->rdev);
|
||||||
|
|
||||||
if (nvt->pkts) {
|
|
||||||
nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts);
|
|
||||||
nvt->pkts = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nvt_dbg_verbose("%s done", __func__);
|
nvt_dbg_verbose("%s done", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1048,7 +1020,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
|
|||||||
|
|
||||||
spin_lock_init(&nvt->nvt_lock);
|
spin_lock_init(&nvt->nvt_lock);
|
||||||
spin_lock_init(&nvt->tx.lock);
|
spin_lock_init(&nvt->tx.lock);
|
||||||
init_ir_raw_event(&nvt->rawir);
|
|
||||||
|
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
/* now claim resources */
|
/* now claim resources */
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ static int debug;
|
|||||||
struct nvt_dev {
|
struct nvt_dev {
|
||||||
struct pnp_dev *pdev;
|
struct pnp_dev *pdev;
|
||||||
struct rc_dev *rdev;
|
struct rc_dev *rdev;
|
||||||
struct ir_raw_event rawir;
|
|
||||||
|
|
||||||
spinlock_t nvt_lock;
|
spinlock_t nvt_lock;
|
||||||
|
|
||||||
|
|||||||
@@ -2858,7 +2858,6 @@ static void ov7xx0_configure(struct sd *sd)
|
|||||||
case 0x60:
|
case 0x60:
|
||||||
PDEBUG(D_PROBE, "Sensor is a OV7660");
|
PDEBUG(D_PROBE, "Sensor is a OV7660");
|
||||||
sd->sensor = SEN_OV7660;
|
sd->sensor = SEN_OV7660;
|
||||||
sd->invert_led = 0;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
|
PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
|
||||||
@@ -3337,7 +3336,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|||||||
case BRIDGE_OV519:
|
case BRIDGE_OV519:
|
||||||
cam->cam_mode = ov519_vga_mode;
|
cam->cam_mode = ov519_vga_mode;
|
||||||
cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
|
cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
|
||||||
sd->invert_led = !sd->invert_led;
|
|
||||||
break;
|
break;
|
||||||
case BRIDGE_OVFX2:
|
case BRIDGE_OVFX2:
|
||||||
cam->cam_mode = ov519_vga_mode;
|
cam->cam_mode = ov519_vga_mode;
|
||||||
@@ -5005,24 +5003,24 @@ static const struct sd_desc sd_desc = {
|
|||||||
/* -- module initialisation -- */
|
/* -- module initialisation -- */
|
||||||
static const struct usb_device_id device_table[] = {
|
static const struct usb_device_id device_table[] = {
|
||||||
{USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
|
{USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
|
||||||
{USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
|
{USB_DEVICE(0x041e, 0x4052),
|
||||||
{USB_DEVICE(0x041e, 0x405f),
|
|
||||||
.driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
|
.driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
|
||||||
|
{USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
|
||||||
{USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
|
{USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
|
||||||
{USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
|
{USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
|
||||||
{USB_DEVICE(0x041e, 0x4064),
|
{USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 },
|
||||||
.driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
|
|
||||||
{USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
|
{USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
|
||||||
{USB_DEVICE(0x041e, 0x4068),
|
{USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 },
|
||||||
|
{USB_DEVICE(0x045e, 0x028c),
|
||||||
.driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
|
.driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
|
||||||
{USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
|
|
||||||
{USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
|
{USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
|
||||||
{USB_DEVICE(0x054c, 0x0155),
|
{USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
|
||||||
.driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
|
|
||||||
{USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
|
{USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
|
||||||
{USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
|
{USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
|
||||||
{USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
|
{USB_DEVICE(0x05a9, 0x0519),
|
||||||
{USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
|
.driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
|
||||||
|
{USB_DEVICE(0x05a9, 0x0530),
|
||||||
|
.driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
|
||||||
{USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
|
{USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
|
||||||
{USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
|
{USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
|
||||||
{USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
|
{USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
|
||||||
|
|||||||
@@ -2386,7 +2386,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
|||||||
reg_w1(gspca_dev, 0x01, 0x22);
|
reg_w1(gspca_dev, 0x01, 0x22);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
reg01 = SCL_SEL_OD | S_PDN_INV;
|
reg01 = SCL_SEL_OD | S_PDN_INV;
|
||||||
reg17 &= MCK_SIZE_MASK;
|
reg17 &= ~MCK_SIZE_MASK;
|
||||||
reg17 |= 0x04; /* clock / 4 */
|
reg17 |= 0x04; /* clock / 4 */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2532,6 +2532,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
|||||||
if (!mode) { /* if 640x480 */
|
if (!mode) { /* if 640x480 */
|
||||||
reg17 &= ~MCK_SIZE_MASK;
|
reg17 &= ~MCK_SIZE_MASK;
|
||||||
reg17 |= 0x04; /* clock / 4 */
|
reg17 |= 0x04; /* clock / 4 */
|
||||||
|
} else {
|
||||||
|
reg01 &= ~SYS_SEL_48M; /* clk 24Mz */
|
||||||
|
reg17 &= ~MCK_SIZE_MASK;
|
||||||
|
reg17 |= 0x02; /* clock / 2 */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SENSOR_OV7630:
|
case SENSOR_OV7630:
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ int pwc_init_controls(struct pwc_device *pdev)
|
|||||||
if (pdev->restore_factory)
|
if (pdev->restore_factory)
|
||||||
pdev->restore_factory->flags = V4L2_CTRL_FLAG_UPDATE;
|
pdev->restore_factory->flags = V4L2_CTRL_FLAG_UPDATE;
|
||||||
|
|
||||||
if (!pdev->features & FEATURE_MOTOR_PANTILT)
|
if (!(pdev->features & FEATURE_MOTOR_PANTILT))
|
||||||
return hdl->error;
|
return hdl->error;
|
||||||
|
|
||||||
/* Motor pan / tilt / reset */
|
/* Motor pan / tilt / reset */
|
||||||
|
|||||||
@@ -1332,6 +1332,8 @@ static __devinit bool viacam_serial_is_enabled(void)
|
|||||||
struct pci_bus *pbus = pci_find_bus(0, 0);
|
struct pci_bus *pbus = pci_find_bus(0, 0);
|
||||||
u8 cbyte;
|
u8 cbyte;
|
||||||
|
|
||||||
|
if (!pbus)
|
||||||
|
return false;
|
||||||
pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
|
pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
|
||||||
VIACAM_SERIAL_CREG, &cbyte);
|
VIACAM_SERIAL_CREG, &cbyte);
|
||||||
if ((cbyte & VIACAM_SERIAL_BIT) == 0)
|
if ((cbyte & VIACAM_SERIAL_BIT) == 0)
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
|
|||||||
if (mrq->done)
|
if (mrq->done)
|
||||||
mrq->done(mrq);
|
mrq->done(mrq);
|
||||||
|
|
||||||
mmc_host_clk_gate(host);
|
mmc_host_clk_release(host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
|
|||||||
mrq->stop->mrq = mrq;
|
mrq->stop->mrq = mrq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mmc_host_clk_ungate(host);
|
mmc_host_clk_hold(host);
|
||||||
led_trigger_event(host->led, LED_FULL);
|
led_trigger_event(host->led, LED_FULL);
|
||||||
host->ops->request(host, mrq);
|
host->ops->request(host, mrq);
|
||||||
}
|
}
|
||||||
@@ -728,15 +728,17 @@ static inline void mmc_set_ios(struct mmc_host *host)
|
|||||||
*/
|
*/
|
||||||
void mmc_set_chip_select(struct mmc_host *host, int mode)
|
void mmc_set_chip_select(struct mmc_host *host, int mode)
|
||||||
{
|
{
|
||||||
|
mmc_host_clk_hold(host);
|
||||||
host->ios.chip_select = mode;
|
host->ios.chip_select = mode;
|
||||||
mmc_set_ios(host);
|
mmc_set_ios(host);
|
||||||
|
mmc_host_clk_release(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the host clock to the highest possible frequency that
|
* Sets the host clock to the highest possible frequency that
|
||||||
* is below "hz".
|
* is below "hz".
|
||||||
*/
|
*/
|
||||||
void mmc_set_clock(struct mmc_host *host, unsigned int hz)
|
static void __mmc_set_clock(struct mmc_host *host, unsigned int hz)
|
||||||
{
|
{
|
||||||
WARN_ON(hz < host->f_min);
|
WARN_ON(hz < host->f_min);
|
||||||
|
|
||||||
@@ -747,6 +749,13 @@ void mmc_set_clock(struct mmc_host *host, unsigned int hz)
|
|||||||
mmc_set_ios(host);
|
mmc_set_ios(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mmc_set_clock(struct mmc_host *host, unsigned int hz)
|
||||||
|
{
|
||||||
|
mmc_host_clk_hold(host);
|
||||||
|
__mmc_set_clock(host, hz);
|
||||||
|
mmc_host_clk_release(host);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MMC_CLKGATE
|
#ifdef CONFIG_MMC_CLKGATE
|
||||||
/*
|
/*
|
||||||
* This gates the clock by setting it to 0 Hz.
|
* This gates the clock by setting it to 0 Hz.
|
||||||
@@ -779,7 +788,7 @@ void mmc_ungate_clock(struct mmc_host *host)
|
|||||||
if (host->clk_old) {
|
if (host->clk_old) {
|
||||||
BUG_ON(host->ios.clock);
|
BUG_ON(host->ios.clock);
|
||||||
/* This call will also set host->clk_gated to false */
|
/* This call will also set host->clk_gated to false */
|
||||||
mmc_set_clock(host, host->clk_old);
|
__mmc_set_clock(host, host->clk_old);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -807,8 +816,10 @@ void mmc_set_ungated(struct mmc_host *host)
|
|||||||
*/
|
*/
|
||||||
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
|
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
|
||||||
{
|
{
|
||||||
|
mmc_host_clk_hold(host);
|
||||||
host->ios.bus_mode = mode;
|
host->ios.bus_mode = mode;
|
||||||
mmc_set_ios(host);
|
mmc_set_ios(host);
|
||||||
|
mmc_host_clk_release(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -816,8 +827,10 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
|
|||||||
*/
|
*/
|
||||||
void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
|
void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
|
||||||
{
|
{
|
||||||
|
mmc_host_clk_hold(host);
|
||||||
host->ios.bus_width = width;
|
host->ios.bus_width = width;
|
||||||
mmc_set_ios(host);
|
mmc_set_ios(host);
|
||||||
|
mmc_host_clk_release(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1015,8 +1028,10 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
|
|||||||
|
|
||||||
ocr &= 3 << bit;
|
ocr &= 3 << bit;
|
||||||
|
|
||||||
|
mmc_host_clk_hold(host);
|
||||||
host->ios.vdd = bit;
|
host->ios.vdd = bit;
|
||||||
mmc_set_ios(host);
|
mmc_set_ios(host);
|
||||||
|
mmc_host_clk_release(host);
|
||||||
} else {
|
} else {
|
||||||
pr_warning("%s: host doesn't support card's voltages\n",
|
pr_warning("%s: host doesn't support card's voltages\n",
|
||||||
mmc_hostname(host));
|
mmc_hostname(host));
|
||||||
@@ -1063,8 +1078,10 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11
|
|||||||
*/
|
*/
|
||||||
void mmc_set_timing(struct mmc_host *host, unsigned int timing)
|
void mmc_set_timing(struct mmc_host *host, unsigned int timing)
|
||||||
{
|
{
|
||||||
|
mmc_host_clk_hold(host);
|
||||||
host->ios.timing = timing;
|
host->ios.timing = timing;
|
||||||
mmc_set_ios(host);
|
mmc_set_ios(host);
|
||||||
|
mmc_host_clk_release(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1072,8 +1089,10 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
|
|||||||
*/
|
*/
|
||||||
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
|
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
|
||||||
{
|
{
|
||||||
|
mmc_host_clk_hold(host);
|
||||||
host->ios.drv_type = drv_type;
|
host->ios.drv_type = drv_type;
|
||||||
mmc_set_ios(host);
|
mmc_set_ios(host);
|
||||||
|
mmc_host_clk_release(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1091,6 +1110,8 @@ static void mmc_power_up(struct mmc_host *host)
|
|||||||
{
|
{
|
||||||
int bit;
|
int bit;
|
||||||
|
|
||||||
|
mmc_host_clk_hold(host);
|
||||||
|
|
||||||
/* If ocr is set, we use it */
|
/* If ocr is set, we use it */
|
||||||
if (host->ocr)
|
if (host->ocr)
|
||||||
bit = ffs(host->ocr) - 1;
|
bit = ffs(host->ocr) - 1;
|
||||||
@@ -1126,10 +1147,14 @@ static void mmc_power_up(struct mmc_host *host)
|
|||||||
* time required to reach a stable voltage.
|
* time required to reach a stable voltage.
|
||||||
*/
|
*/
|
||||||
mmc_delay(10);
|
mmc_delay(10);
|
||||||
|
|
||||||
|
mmc_host_clk_release(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mmc_power_off(struct mmc_host *host)
|
static void mmc_power_off(struct mmc_host *host)
|
||||||
{
|
{
|
||||||
|
mmc_host_clk_hold(host);
|
||||||
|
|
||||||
host->ios.clock = 0;
|
host->ios.clock = 0;
|
||||||
host->ios.vdd = 0;
|
host->ios.vdd = 0;
|
||||||
|
|
||||||
@@ -1147,6 +1172,8 @@ static void mmc_power_off(struct mmc_host *host)
|
|||||||
host->ios.bus_width = MMC_BUS_WIDTH_1;
|
host->ios.bus_width = MMC_BUS_WIDTH_1;
|
||||||
host->ios.timing = MMC_TIMING_LEGACY;
|
host->ios.timing = MMC_TIMING_LEGACY;
|
||||||
mmc_set_ios(host);
|
mmc_set_ios(host);
|
||||||
|
|
||||||
|
mmc_host_clk_release(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -119,14 +119,14 @@ static void mmc_host_clk_gate_work(struct work_struct *work)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mmc_host_clk_ungate - ungate hardware MCI clocks
|
* mmc_host_clk_hold - ungate hardware MCI clocks
|
||||||
* @host: host to ungate.
|
* @host: host to ungate.
|
||||||
*
|
*
|
||||||
* Makes sure the host ios.clock is restored to a non-zero value
|
* Makes sure the host ios.clock is restored to a non-zero value
|
||||||
* past this call. Increase clock reference count and ungate clock
|
* past this call. Increase clock reference count and ungate clock
|
||||||
* if we're the first user.
|
* if we're the first user.
|
||||||
*/
|
*/
|
||||||
void mmc_host_clk_ungate(struct mmc_host *host)
|
void mmc_host_clk_hold(struct mmc_host *host)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
@@ -164,14 +164,14 @@ static bool mmc_host_may_gate_card(struct mmc_card *card)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mmc_host_clk_gate - gate off hardware MCI clocks
|
* mmc_host_clk_release - gate off hardware MCI clocks
|
||||||
* @host: host to gate.
|
* @host: host to gate.
|
||||||
*
|
*
|
||||||
* Calls the host driver with ios.clock set to zero as often as possible
|
* Calls the host driver with ios.clock set to zero as often as possible
|
||||||
* in order to gate off hardware MCI clocks. Decrease clock reference
|
* in order to gate off hardware MCI clocks. Decrease clock reference
|
||||||
* count and schedule disabling of clock.
|
* count and schedule disabling of clock.
|
||||||
*/
|
*/
|
||||||
void mmc_host_clk_gate(struct mmc_host *host)
|
void mmc_host_clk_release(struct mmc_host *host)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ void mmc_host_clk_gate(struct mmc_host *host)
|
|||||||
host->clk_requests--;
|
host->clk_requests--;
|
||||||
if (mmc_host_may_gate_card(host->card) &&
|
if (mmc_host_may_gate_card(host->card) &&
|
||||||
!host->clk_requests)
|
!host->clk_requests)
|
||||||
schedule_work(&host->clk_gate_work);
|
queue_work(system_nrt_wq, &host->clk_gate_work);
|
||||||
spin_unlock_irqrestore(&host->clk_lock, flags);
|
spin_unlock_irqrestore(&host->clk_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +231,7 @@ static inline void mmc_host_clk_exit(struct mmc_host *host)
|
|||||||
if (cancel_work_sync(&host->clk_gate_work))
|
if (cancel_work_sync(&host->clk_gate_work))
|
||||||
mmc_host_clk_gate_delayed(host);
|
mmc_host_clk_gate_delayed(host);
|
||||||
if (host->clk_gated)
|
if (host->clk_gated)
|
||||||
mmc_host_clk_ungate(host);
|
mmc_host_clk_hold(host);
|
||||||
/* There should be only one user now */
|
/* There should be only one user now */
|
||||||
WARN_ON(host->clk_requests > 1);
|
WARN_ON(host->clk_requests > 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,16 +16,16 @@ int mmc_register_host_class(void);
|
|||||||
void mmc_unregister_host_class(void);
|
void mmc_unregister_host_class(void);
|
||||||
|
|
||||||
#ifdef CONFIG_MMC_CLKGATE
|
#ifdef CONFIG_MMC_CLKGATE
|
||||||
void mmc_host_clk_ungate(struct mmc_host *host);
|
void mmc_host_clk_hold(struct mmc_host *host);
|
||||||
void mmc_host_clk_gate(struct mmc_host *host);
|
void mmc_host_clk_release(struct mmc_host *host);
|
||||||
unsigned int mmc_host_clk_rate(struct mmc_host *host);
|
unsigned int mmc_host_clk_rate(struct mmc_host *host);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static inline void mmc_host_clk_ungate(struct mmc_host *host)
|
static inline void mmc_host_clk_hold(struct mmc_host *host)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void mmc_host_clk_gate(struct mmc_host *host)
|
static inline void mmc_host_clk_release(struct mmc_host *host)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -469,56 +469,75 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
|
static void sd_update_bus_speed_mode(struct mmc_card *card)
|
||||||
{
|
{
|
||||||
unsigned int bus_speed = 0, timing = 0;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the host doesn't support any of the UHS-I modes, fallback on
|
* If the host doesn't support any of the UHS-I modes, fallback on
|
||||||
* default speed.
|
* default speed.
|
||||||
*/
|
*/
|
||||||
if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
|
if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
|
||||||
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)))
|
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))) {
|
||||||
return 0;
|
card->sd_bus_speed = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((card->host->caps & MMC_CAP_UHS_SDR104) &&
|
if ((card->host->caps & MMC_CAP_UHS_SDR104) &&
|
||||||
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) {
|
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) {
|
||||||
bus_speed = UHS_SDR104_BUS_SPEED;
|
card->sd_bus_speed = UHS_SDR104_BUS_SPEED;
|
||||||
timing = MMC_TIMING_UHS_SDR104;
|
|
||||||
card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
|
|
||||||
} else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
|
} else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
|
||||||
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
|
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
|
||||||
bus_speed = UHS_DDR50_BUS_SPEED;
|
card->sd_bus_speed = UHS_DDR50_BUS_SPEED;
|
||||||
timing = MMC_TIMING_UHS_DDR50;
|
|
||||||
card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
|
|
||||||
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
|
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
|
||||||
MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
|
MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
|
||||||
SD_MODE_UHS_SDR50)) {
|
SD_MODE_UHS_SDR50)) {
|
||||||
bus_speed = UHS_SDR50_BUS_SPEED;
|
card->sd_bus_speed = UHS_SDR50_BUS_SPEED;
|
||||||
timing = MMC_TIMING_UHS_SDR50;
|
|
||||||
card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
|
|
||||||
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
|
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
|
||||||
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
|
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
|
||||||
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
|
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
|
||||||
bus_speed = UHS_SDR25_BUS_SPEED;
|
card->sd_bus_speed = UHS_SDR25_BUS_SPEED;
|
||||||
timing = MMC_TIMING_UHS_SDR25;
|
|
||||||
card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
|
|
||||||
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
|
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
|
||||||
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
|
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
|
||||||
MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
|
MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
|
||||||
SD_MODE_UHS_SDR12)) {
|
SD_MODE_UHS_SDR12)) {
|
||||||
bus_speed = UHS_SDR12_BUS_SPEED;
|
card->sd_bus_speed = UHS_SDR12_BUS_SPEED;
|
||||||
timing = MMC_TIMING_UHS_SDR12;
|
}
|
||||||
card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
card->sd_bus_speed = bus_speed;
|
static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
|
||||||
err = mmc_sd_switch(card, 1, 0, bus_speed, status);
|
{
|
||||||
|
int err;
|
||||||
|
unsigned int timing = 0;
|
||||||
|
|
||||||
|
switch (card->sd_bus_speed) {
|
||||||
|
case UHS_SDR104_BUS_SPEED:
|
||||||
|
timing = MMC_TIMING_UHS_SDR104;
|
||||||
|
card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
|
||||||
|
break;
|
||||||
|
case UHS_DDR50_BUS_SPEED:
|
||||||
|
timing = MMC_TIMING_UHS_DDR50;
|
||||||
|
card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
|
||||||
|
break;
|
||||||
|
case UHS_SDR50_BUS_SPEED:
|
||||||
|
timing = MMC_TIMING_UHS_SDR50;
|
||||||
|
card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
|
||||||
|
break;
|
||||||
|
case UHS_SDR25_BUS_SPEED:
|
||||||
|
timing = MMC_TIMING_UHS_SDR25;
|
||||||
|
card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
|
||||||
|
break;
|
||||||
|
case UHS_SDR12_BUS_SPEED:
|
||||||
|
timing = MMC_TIMING_UHS_SDR12;
|
||||||
|
card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = mmc_sd_switch(card, 1, 0, card->sd_bus_speed, status);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if ((status[16] & 0xF) != bus_speed)
|
if ((status[16] & 0xF) != card->sd_bus_speed)
|
||||||
printk(KERN_WARNING "%s: Problem setting bus speed mode!\n",
|
printk(KERN_WARNING "%s: Problem setting bus speed mode!\n",
|
||||||
mmc_hostname(card->host));
|
mmc_hostname(card->host));
|
||||||
else {
|
else {
|
||||||
@@ -618,18 +637,24 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
|
|||||||
mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
|
mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select the bus speed mode depending on host
|
||||||
|
* and card capability.
|
||||||
|
*/
|
||||||
|
sd_update_bus_speed_mode(card);
|
||||||
|
|
||||||
/* Set the driver strength for the card */
|
/* Set the driver strength for the card */
|
||||||
err = sd_select_driver_type(card, status);
|
err = sd_select_driver_type(card, status);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Set bus speed mode of the card */
|
/* Set current limit for the card */
|
||||||
err = sd_set_bus_speed_mode(card, status);
|
err = sd_set_current_limit(card, status);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Set current limit for the card */
|
/* Set bus speed mode of the card */
|
||||||
err = sd_set_current_limit(card, status);
|
err = sd_set_bus_speed_mode(card, status);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/module.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/mmc/host.h>
|
#include <linux/mmc/host.h>
|
||||||
#include <linux/mmc/mmc.h>
|
#include <linux/mmc/mmc.h>
|
||||||
|
|||||||
@@ -302,6 +302,8 @@ static int sdhci_s3c_platform_8bit_width(struct sdhci_host *host, int width)
|
|||||||
ctrl &= ~SDHCI_CTRL_8BITBUS;
|
ctrl &= ~SDHCI_CTRL_8BITBUS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
ctrl &= ~SDHCI_CTRL_4BITBUS;
|
||||||
|
ctrl &= ~SDHCI_CTRL_8BITBUS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,11 +120,11 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
|
|||||||
mmc_data->hclk = clk_get_rate(priv->clk);
|
mmc_data->hclk = clk_get_rate(priv->clk);
|
||||||
mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
|
mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
|
||||||
mmc_data->get_cd = sh_mobile_sdhi_get_cd;
|
mmc_data->get_cd = sh_mobile_sdhi_get_cd;
|
||||||
if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
|
|
||||||
mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
|
|
||||||
mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
|
mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
|
||||||
if (p) {
|
if (p) {
|
||||||
mmc_data->flags = p->tmio_flags;
|
mmc_data->flags = p->tmio_flags;
|
||||||
|
if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
|
||||||
|
mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
|
||||||
mmc_data->ocr_mask = p->tmio_ocr_mask;
|
mmc_data->ocr_mask = p->tmio_ocr_mask;
|
||||||
mmc_data->capabilities |= p->tmio_caps;
|
mmc_data->capabilities |= p->tmio_caps;
|
||||||
|
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
|
|||||||
|
|
||||||
#define ubi_dbg_msg(fmt, ...) do { \
|
#define ubi_dbg_msg(fmt, ...) do { \
|
||||||
if (0) \
|
if (0) \
|
||||||
pr_debug(fmt "\n", ##__VA_ARGS__); \
|
printk(KERN_DEBUG fmt "\n", ##__VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define dbg_msg(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__)
|
#define dbg_msg(fmt, ...) ubi_dbg_msg(fmt, ##__VA_ARGS__)
|
||||||
|
|||||||
@@ -308,8 +308,11 @@ static void am79c961_timer(unsigned long data)
|
|||||||
struct net_device *dev = (struct net_device *)data;
|
struct net_device *dev = (struct net_device *)data;
|
||||||
struct dev_priv *priv = netdev_priv(dev);
|
struct dev_priv *priv = netdev_priv(dev);
|
||||||
unsigned int lnkstat, carrier;
|
unsigned int lnkstat, carrier;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&priv->chip_lock, flags);
|
||||||
lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST;
|
lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST;
|
||||||
|
spin_unlock_irqrestore(&priv->chip_lock, flags);
|
||||||
carrier = netif_carrier_ok(dev);
|
carrier = netif_carrier_ok(dev);
|
||||||
|
|
||||||
if (lnkstat && !carrier) {
|
if (lnkstat && !carrier) {
|
||||||
|
|||||||
@@ -169,7 +169,9 @@ void pci_configure_slot(struct pci_dev *dev)
|
|||||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
|
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pcie_bus_configure_settings(dev->bus, dev->bus->self->pcie_mpss);
|
if (dev->bus && dev->bus->self)
|
||||||
|
pcie_bus_configure_settings(dev->bus,
|
||||||
|
dev->bus->self->pcie_mpss);
|
||||||
|
|
||||||
memset(&hpp, 0, sizeof(hpp));
|
memset(&hpp, 0, sizeof(hpp));
|
||||||
ret = pci_get_hp_params(dev, &hpp);
|
ret = pci_get_hp_params(dev, &hpp);
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
|
|||||||
unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE;
|
unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE;
|
||||||
unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
|
unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
|
||||||
|
|
||||||
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PERFORMANCE;
|
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_SAFE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The default CLS is used if arch didn't set CLS explicitly and not
|
* The default CLS is used if arch didn't set CLS explicitly and not
|
||||||
|
|||||||
@@ -1396,34 +1396,37 @@ static void pcie_write_mps(struct pci_dev *dev, int mps)
|
|||||||
|
|
||||||
static void pcie_write_mrrs(struct pci_dev *dev, int mps)
|
static void pcie_write_mrrs(struct pci_dev *dev, int mps)
|
||||||
{
|
{
|
||||||
int rc, mrrs;
|
int rc, mrrs, dev_mpss;
|
||||||
|
|
||||||
if (pcie_bus_config == PCIE_BUS_PERFORMANCE) {
|
/* In the "safe" case, do not configure the MRRS. There appear to be
|
||||||
int dev_mpss = 128 << dev->pcie_mpss;
|
* issues with setting MRRS to 0 on a number of devices.
|
||||||
|
|
||||||
/* For Max performance, the MRRS must be set to the largest
|
|
||||||
* supported value. However, it cannot be configured larger
|
|
||||||
* than the MPS the device or the bus can support. This assumes
|
|
||||||
* that the largest MRRS available on the device cannot be
|
|
||||||
* smaller than the device MPSS.
|
|
||||||
*/
|
*/
|
||||||
mrrs = mps < dev_mpss ? mps : dev_mpss;
|
|
||||||
} else
|
|
||||||
/* In the "safe" case, configure the MRRS for fairness on the
|
|
||||||
* bus by making all devices have the same size
|
|
||||||
*/
|
|
||||||
mrrs = mps;
|
|
||||||
|
|
||||||
|
if (pcie_bus_config != PCIE_BUS_PERFORMANCE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dev_mpss = 128 << dev->pcie_mpss;
|
||||||
|
|
||||||
|
/* For Max performance, the MRRS must be set to the largest supported
|
||||||
|
* value. However, it cannot be configured larger than the MPS the
|
||||||
|
* device or the bus can support. This assumes that the largest MRRS
|
||||||
|
* available on the device cannot be smaller than the device MPSS.
|
||||||
|
*/
|
||||||
|
mrrs = min(mps, dev_mpss);
|
||||||
|
|
||||||
/* MRRS is a R/W register. Invalid values can be written, but a
|
/* MRRS is a R/W register. Invalid values can be written, but a
|
||||||
* subsiquent read will verify if the value is acceptable or not.
|
* subsequent read will verify if the value is acceptable or not.
|
||||||
* If the MRRS value provided is not acceptable (e.g., too large),
|
* If the MRRS value provided is not acceptable (e.g., too large),
|
||||||
* shrink the value until it is acceptable to the HW.
|
* shrink the value until it is acceptable to the HW.
|
||||||
*/
|
*/
|
||||||
while (mrrs != pcie_get_readrq(dev) && mrrs >= 128) {
|
while (mrrs != pcie_get_readrq(dev) && mrrs >= 128) {
|
||||||
|
dev_warn(&dev->dev, "Attempting to modify the PCI-E MRRS value"
|
||||||
|
" to %d. If any issues are encountered, please try "
|
||||||
|
"running with pci=pcie_bus_safe\n", mrrs);
|
||||||
rc = pcie_set_readrq(dev, mrrs);
|
rc = pcie_set_readrq(dev, mrrs);
|
||||||
if (rc)
|
if (rc)
|
||||||
dev_err(&dev->dev, "Failed attempting to set the MRRS\n");
|
dev_err(&dev->dev,
|
||||||
|
"Failed attempting to set the MRRS\n");
|
||||||
|
|
||||||
mrrs /= 2;
|
mrrs /= 2;
|
||||||
}
|
}
|
||||||
@@ -1436,13 +1439,13 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
|
|||||||
if (!pci_is_pcie(dev))
|
if (!pci_is_pcie(dev))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dev_info(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n",
|
dev_dbg(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n",
|
||||||
pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev));
|
pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev));
|
||||||
|
|
||||||
pcie_write_mps(dev, mps);
|
pcie_write_mps(dev, mps);
|
||||||
pcie_write_mrrs(dev, mps);
|
pcie_write_mrrs(dev, mps);
|
||||||
|
|
||||||
dev_info(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n",
|
dev_dbg(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n",
|
||||||
pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev));
|
pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1456,9 +1459,6 @@ void pcie_bus_configure_settings(struct pci_bus *bus, u8 mpss)
|
|||||||
{
|
{
|
||||||
u8 smpss = mpss;
|
u8 smpss = mpss;
|
||||||
|
|
||||||
if (!bus->self)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!pci_is_pcie(bus->self))
|
if (!pci_is_pcie(bus->self))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
*/
|
*/
|
||||||
struct ep93xx_rtc {
|
struct ep93xx_rtc {
|
||||||
void __iomem *mmio_base;
|
void __iomem *mmio_base;
|
||||||
|
struct rtc_device *rtc;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload,
|
static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload,
|
||||||
@@ -130,7 +131,6 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct ep93xx_rtc *ep93xx_rtc;
|
struct ep93xx_rtc *ep93xx_rtc;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct rtc_device *rtc;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL);
|
ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL);
|
||||||
@@ -151,12 +151,12 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev)
|
|||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
pdev->dev.platform_data = ep93xx_rtc;
|
pdev->dev.platform_data = ep93xx_rtc;
|
||||||
platform_set_drvdata(pdev, rtc);
|
platform_set_drvdata(pdev, ep93xx_rtc);
|
||||||
|
|
||||||
rtc = rtc_device_register(pdev->name,
|
ep93xx_rtc->rtc = rtc_device_register(pdev->name,
|
||||||
&pdev->dev, &ep93xx_rtc_ops, THIS_MODULE);
|
&pdev->dev, &ep93xx_rtc_ops, THIS_MODULE);
|
||||||
if (IS_ERR(rtc)) {
|
if (IS_ERR(ep93xx_rtc->rtc)) {
|
||||||
err = PTR_ERR(rtc);
|
err = PTR_ERR(ep93xx_rtc->rtc);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
rtc_device_unregister(rtc);
|
rtc_device_unregister(ep93xx_rtc->rtc);
|
||||||
exit:
|
exit:
|
||||||
platform_set_drvdata(pdev, NULL);
|
platform_set_drvdata(pdev, NULL);
|
||||||
pdev->dev.platform_data = NULL;
|
pdev->dev.platform_data = NULL;
|
||||||
@@ -176,11 +176,11 @@ exit:
|
|||||||
|
|
||||||
static int __exit ep93xx_rtc_remove(struct platform_device *pdev)
|
static int __exit ep93xx_rtc_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct rtc_device *rtc = platform_get_drvdata(pdev);
|
struct ep93xx_rtc *ep93xx_rtc = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
|
sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
|
||||||
platform_set_drvdata(pdev, NULL);
|
platform_set_drvdata(pdev, NULL);
|
||||||
rtc_device_unregister(rtc);
|
rtc_device_unregister(ep93xx_rtc->rtc);
|
||||||
pdev->dev.platform_data = NULL;
|
pdev->dev.platform_data = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
|
|||||||
time -= tm->tm_hour * 3600;
|
time -= tm->tm_hour * 3600;
|
||||||
tm->tm_min = time / 60;
|
tm->tm_min = time / 60;
|
||||||
tm->tm_sec = time - tm->tm_min * 60;
|
tm->tm_sec = time - tm->tm_min * 60;
|
||||||
|
|
||||||
|
tm->tm_isdst = 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rtc_time_to_tm);
|
EXPORT_SYMBOL(rtc_time_to_tm);
|
||||||
|
|
||||||
|
|||||||
@@ -362,14 +362,6 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
|
|||||||
int res;
|
int res;
|
||||||
u8 rd_reg;
|
u8 rd_reg;
|
||||||
|
|
||||||
#ifdef CONFIG_LOCKDEP
|
|
||||||
/* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
|
|
||||||
* we don't want and can't tolerate. Although it might be
|
|
||||||
* friendlier not to borrow this thread context...
|
|
||||||
*/
|
|
||||||
local_irq_enable();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
|
res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
|
||||||
if (res)
|
if (res)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -428,24 +420,12 @@ static struct rtc_class_ops twl_rtc_ops = {
|
|||||||
static int __devinit twl_rtc_probe(struct platform_device *pdev)
|
static int __devinit twl_rtc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct rtc_device *rtc;
|
struct rtc_device *rtc;
|
||||||
int ret = 0;
|
int ret = -EINVAL;
|
||||||
int irq = platform_get_irq(pdev, 0);
|
int irq = platform_get_irq(pdev, 0);
|
||||||
u8 rd_reg;
|
u8 rd_reg;
|
||||||
|
|
||||||
if (irq <= 0)
|
if (irq <= 0)
|
||||||
return -EINVAL;
|
goto out1;
|
||||||
|
|
||||||
rtc = rtc_device_register(pdev->name,
|
|
||||||
&pdev->dev, &twl_rtc_ops, THIS_MODULE);
|
|
||||||
if (IS_ERR(rtc)) {
|
|
||||||
ret = PTR_ERR(rtc);
|
|
||||||
dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
|
|
||||||
PTR_ERR(rtc));
|
|
||||||
goto out0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, rtc);
|
|
||||||
|
|
||||||
ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
|
ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -462,14 +442,6 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out1;
|
goto out1;
|
||||||
|
|
||||||
ret = request_irq(irq, twl_rtc_interrupt,
|
|
||||||
IRQF_TRIGGER_RISING,
|
|
||||||
dev_name(&rtc->dev), rtc);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(&pdev->dev, "IRQ is not free.\n");
|
|
||||||
goto out1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (twl_class_is_6030()) {
|
if (twl_class_is_6030()) {
|
||||||
twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
|
twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
|
||||||
REG_INT_MSK_LINE_A);
|
REG_INT_MSK_LINE_A);
|
||||||
@@ -480,28 +452,44 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
|
|||||||
/* Check RTC module status, Enable if it is off */
|
/* Check RTC module status, Enable if it is off */
|
||||||
ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
|
ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out2;
|
goto out1;
|
||||||
|
|
||||||
if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
|
if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
|
||||||
dev_info(&pdev->dev, "Enabling TWL-RTC.\n");
|
dev_info(&pdev->dev, "Enabling TWL-RTC.\n");
|
||||||
rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
|
rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
|
||||||
ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
|
ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out2;
|
goto out1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init cached IRQ enable bits */
|
/* init cached IRQ enable bits */
|
||||||
ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
|
ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out2;
|
goto out1;
|
||||||
|
|
||||||
return ret;
|
rtc = rtc_device_register(pdev->name,
|
||||||
|
&pdev->dev, &twl_rtc_ops, THIS_MODULE);
|
||||||
|
if (IS_ERR(rtc)) {
|
||||||
|
ret = PTR_ERR(rtc);
|
||||||
|
dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
|
||||||
|
PTR_ERR(rtc));
|
||||||
|
goto out1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
|
||||||
|
IRQF_TRIGGER_RISING,
|
||||||
|
dev_name(&rtc->dev), rtc);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(&pdev->dev, "IRQ is not free.\n");
|
||||||
|
goto out2;
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, rtc);
|
||||||
|
return 0;
|
||||||
|
|
||||||
out2:
|
out2:
|
||||||
free_irq(irq, rtc);
|
|
||||||
out1:
|
|
||||||
rtc_device_unregister(rtc);
|
rtc_device_unregister(rtc);
|
||||||
out0:
|
out1:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
config SCSI_QLA_ISCSI
|
config SCSI_QLA_ISCSI
|
||||||
tristate "QLogic ISP4XXX and ISP82XX host adapter family support"
|
tristate "QLogic ISP4XXX and ISP82XX host adapter family support"
|
||||||
depends on PCI && SCSI
|
depends on PCI && SCSI && NET
|
||||||
select SCSI_ISCSI_ATTRS
|
select SCSI_ISCSI_ATTRS
|
||||||
---help---
|
---help---
|
||||||
This driver supports the QLogic 40xx (ISP4XXX) and 8022 (ISP82XX)
|
This driver supports the QLogic 40xx (ISP4XXX) and 8022 (ISP82XX)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include <asm/backlight.h>
|
#include <asm/backlight.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char const *backlight_types[] = {
|
static const char *const backlight_types[] = {
|
||||||
[BACKLIGHT_RAW] = "raw",
|
[BACKLIGHT_RAW] = "raw",
|
||||||
[BACKLIGHT_PLATFORM] = "platform",
|
[BACKLIGHT_PLATFORM] = "platform",
|
||||||
[BACKLIGHT_FIRMWARE] = "firmware",
|
[BACKLIGHT_FIRMWARE] = "firmware",
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ extern struct kmem_cache *v9fs_inode_cache;
|
|||||||
|
|
||||||
struct inode *v9fs_alloc_inode(struct super_block *sb);
|
struct inode *v9fs_alloc_inode(struct super_block *sb);
|
||||||
void v9fs_destroy_inode(struct inode *inode);
|
void v9fs_destroy_inode(struct inode *inode);
|
||||||
struct inode *v9fs_get_inode(struct super_block *sb, int mode);
|
struct inode *v9fs_get_inode(struct super_block *sb, int mode, dev_t);
|
||||||
int v9fs_init_inode(struct v9fs_session_info *v9ses,
|
int v9fs_init_inode(struct v9fs_session_info *v9ses,
|
||||||
struct inode *inode, int mode);
|
struct inode *inode, int mode, dev_t);
|
||||||
void v9fs_evict_inode(struct inode *inode);
|
void v9fs_evict_inode(struct inode *inode);
|
||||||
ino_t v9fs_qid2ino(struct p9_qid *qid);
|
ino_t v9fs_qid2ino(struct p9_qid *qid);
|
||||||
void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
|
void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
|
||||||
@@ -83,4 +83,6 @@ static inline void v9fs_invalidate_inode_attr(struct inode *inode)
|
|||||||
v9inode->cache_validity |= V9FS_INO_INVALID_ATTR;
|
v9inode->cache_validity |= V9FS_INO_INVALID_ATTR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int v9fs_open_to_dotl_flags(int flags);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
|
|||||||
v9inode = V9FS_I(inode);
|
v9inode = V9FS_I(inode);
|
||||||
v9ses = v9fs_inode2v9ses(inode);
|
v9ses = v9fs_inode2v9ses(inode);
|
||||||
if (v9fs_proto_dotl(v9ses))
|
if (v9fs_proto_dotl(v9ses))
|
||||||
omode = file->f_flags;
|
omode = v9fs_open_to_dotl_flags(file->f_flags);
|
||||||
else
|
else
|
||||||
omode = v9fs_uflags2omode(file->f_flags,
|
omode = v9fs_uflags2omode(file->f_flags,
|
||||||
v9fs_proto_dotu(v9ses));
|
v9fs_proto_dotu(v9ses));
|
||||||
@@ -169,7 +169,18 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
|
|||||||
|
|
||||||
/* convert posix lock to p9 tlock args */
|
/* convert posix lock to p9 tlock args */
|
||||||
memset(&flock, 0, sizeof(flock));
|
memset(&flock, 0, sizeof(flock));
|
||||||
flock.type = fl->fl_type;
|
/* map the lock type */
|
||||||
|
switch (fl->fl_type) {
|
||||||
|
case F_RDLCK:
|
||||||
|
flock.type = P9_LOCK_TYPE_RDLCK;
|
||||||
|
break;
|
||||||
|
case F_WRLCK:
|
||||||
|
flock.type = P9_LOCK_TYPE_WRLCK;
|
||||||
|
break;
|
||||||
|
case F_UNLCK:
|
||||||
|
flock.type = P9_LOCK_TYPE_UNLCK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
flock.start = fl->fl_start;
|
flock.start = fl->fl_start;
|
||||||
if (fl->fl_end == OFFSET_MAX)
|
if (fl->fl_end == OFFSET_MAX)
|
||||||
flock.length = 0;
|
flock.length = 0;
|
||||||
@@ -245,7 +256,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
|
|||||||
|
|
||||||
/* convert posix lock to p9 tgetlock args */
|
/* convert posix lock to p9 tgetlock args */
|
||||||
memset(&glock, 0, sizeof(glock));
|
memset(&glock, 0, sizeof(glock));
|
||||||
glock.type = fl->fl_type;
|
glock.type = P9_LOCK_TYPE_UNLCK;
|
||||||
glock.start = fl->fl_start;
|
glock.start = fl->fl_start;
|
||||||
if (fl->fl_end == OFFSET_MAX)
|
if (fl->fl_end == OFFSET_MAX)
|
||||||
glock.length = 0;
|
glock.length = 0;
|
||||||
@@ -257,17 +268,26 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
|
|||||||
res = p9_client_getlock_dotl(fid, &glock);
|
res = p9_client_getlock_dotl(fid, &glock);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
if (glock.type != F_UNLCK) {
|
/* map 9p lock type to os lock type */
|
||||||
fl->fl_type = glock.type;
|
switch (glock.type) {
|
||||||
|
case P9_LOCK_TYPE_RDLCK:
|
||||||
|
fl->fl_type = F_RDLCK;
|
||||||
|
break;
|
||||||
|
case P9_LOCK_TYPE_WRLCK:
|
||||||
|
fl->fl_type = F_WRLCK;
|
||||||
|
break;
|
||||||
|
case P9_LOCK_TYPE_UNLCK:
|
||||||
|
fl->fl_type = F_UNLCK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (glock.type != P9_LOCK_TYPE_UNLCK) {
|
||||||
fl->fl_start = glock.start;
|
fl->fl_start = glock.start;
|
||||||
if (glock.length == 0)
|
if (glock.length == 0)
|
||||||
fl->fl_end = OFFSET_MAX;
|
fl->fl_end = OFFSET_MAX;
|
||||||
else
|
else
|
||||||
fl->fl_end = glock.start + glock.length - 1;
|
fl->fl_end = glock.start + glock.length - 1;
|
||||||
fl->fl_pid = glock.proc_id;
|
fl->fl_pid = glock.proc_id;
|
||||||
} else
|
}
|
||||||
fl->fl_type = F_UNLCK;
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,15 +95,18 @@ static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode)
|
|||||||
/**
|
/**
|
||||||
* p9mode2unixmode- convert plan9 mode bits to unix mode bits
|
* p9mode2unixmode- convert plan9 mode bits to unix mode bits
|
||||||
* @v9ses: v9fs session information
|
* @v9ses: v9fs session information
|
||||||
* @mode: mode to convert
|
* @stat: p9_wstat from which mode need to be derived
|
||||||
|
* @rdev: major number, minor number in case of device files.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
static int p9mode2unixmode(struct v9fs_session_info *v9ses,
|
||||||
static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
|
struct p9_wstat *stat, dev_t *rdev)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
int mode = stat->mode;
|
||||||
|
|
||||||
res = mode & 0777;
|
res = mode & S_IALLUGO;
|
||||||
|
*rdev = 0;
|
||||||
|
|
||||||
if ((mode & P9_DMDIR) == P9_DMDIR)
|
if ((mode & P9_DMDIR) == P9_DMDIR)
|
||||||
res |= S_IFDIR;
|
res |= S_IFDIR;
|
||||||
@@ -116,9 +119,26 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
|
|||||||
&& (v9ses->nodev == 0))
|
&& (v9ses->nodev == 0))
|
||||||
res |= S_IFIFO;
|
res |= S_IFIFO;
|
||||||
else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
|
else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
|
||||||
&& (v9ses->nodev == 0))
|
&& (v9ses->nodev == 0)) {
|
||||||
|
char type = 0, ext[32];
|
||||||
|
int major = -1, minor = -1;
|
||||||
|
|
||||||
|
strncpy(ext, stat->extension, sizeof(ext));
|
||||||
|
sscanf(ext, "%c %u %u", &type, &major, &minor);
|
||||||
|
switch (type) {
|
||||||
|
case 'c':
|
||||||
|
res |= S_IFCHR;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
res |= S_IFBLK;
|
res |= S_IFBLK;
|
||||||
else
|
break;
|
||||||
|
default:
|
||||||
|
P9_DPRINTK(P9_DEBUG_ERROR,
|
||||||
|
"Unknown special type %c %s\n", type,
|
||||||
|
stat->extension);
|
||||||
|
};
|
||||||
|
*rdev = MKDEV(major, minor);
|
||||||
|
} else
|
||||||
res |= S_IFREG;
|
res |= S_IFREG;
|
||||||
|
|
||||||
if (v9fs_proto_dotu(v9ses)) {
|
if (v9fs_proto_dotu(v9ses)) {
|
||||||
@@ -131,7 +151,6 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
|
|||||||
if ((mode & P9_DMSETVTX) == P9_DMSETVTX)
|
if ((mode & P9_DMSETVTX) == P9_DMSETVTX)
|
||||||
res |= S_ISVTX;
|
res |= S_ISVTX;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,13 +261,13 @@ void v9fs_destroy_inode(struct inode *inode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int v9fs_init_inode(struct v9fs_session_info *v9ses,
|
int v9fs_init_inode(struct v9fs_session_info *v9ses,
|
||||||
struct inode *inode, int mode)
|
struct inode *inode, int mode, dev_t rdev)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
inode_init_owner(inode, NULL, mode);
|
inode_init_owner(inode, NULL, mode);
|
||||||
inode->i_blocks = 0;
|
inode->i_blocks = 0;
|
||||||
inode->i_rdev = 0;
|
inode->i_rdev = rdev;
|
||||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||||
inode->i_mapping->a_ops = &v9fs_addr_operations;
|
inode->i_mapping->a_ops = &v9fs_addr_operations;
|
||||||
|
|
||||||
@@ -335,7 +354,7 @@ error:
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct inode *v9fs_get_inode(struct super_block *sb, int mode)
|
struct inode *v9fs_get_inode(struct super_block *sb, int mode, dev_t rdev)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
@@ -348,7 +367,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
|
|||||||
P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
|
P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
err = v9fs_init_inode(v9ses, inode, mode);
|
err = v9fs_init_inode(v9ses, inode, mode, rdev);
|
||||||
if (err) {
|
if (err) {
|
||||||
iput(inode);
|
iput(inode);
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
@@ -435,11 +454,12 @@ void v9fs_evict_inode(struct inode *inode)
|
|||||||
static int v9fs_test_inode(struct inode *inode, void *data)
|
static int v9fs_test_inode(struct inode *inode, void *data)
|
||||||
{
|
{
|
||||||
int umode;
|
int umode;
|
||||||
|
dev_t rdev;
|
||||||
struct v9fs_inode *v9inode = V9FS_I(inode);
|
struct v9fs_inode *v9inode = V9FS_I(inode);
|
||||||
struct p9_wstat *st = (struct p9_wstat *)data;
|
struct p9_wstat *st = (struct p9_wstat *)data;
|
||||||
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
|
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
|
||||||
|
|
||||||
umode = p9mode2unixmode(v9ses, st->mode);
|
umode = p9mode2unixmode(v9ses, st, &rdev);
|
||||||
/* don't match inode of different type */
|
/* don't match inode of different type */
|
||||||
if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
|
if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -473,6 +493,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
|
|||||||
struct p9_wstat *st,
|
struct p9_wstat *st,
|
||||||
int new)
|
int new)
|
||||||
{
|
{
|
||||||
|
dev_t rdev;
|
||||||
int retval, umode;
|
int retval, umode;
|
||||||
unsigned long i_ino;
|
unsigned long i_ino;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
@@ -496,8 +517,8 @@ static struct inode *v9fs_qid_iget(struct super_block *sb,
|
|||||||
* later.
|
* later.
|
||||||
*/
|
*/
|
||||||
inode->i_ino = i_ino;
|
inode->i_ino = i_ino;
|
||||||
umode = p9mode2unixmode(v9ses, st->mode);
|
umode = p9mode2unixmode(v9ses, st, &rdev);
|
||||||
retval = v9fs_init_inode(v9ses, inode, umode);
|
retval = v9fs_init_inode(v9ses, inode, umode, rdev);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@@ -531,6 +552,19 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
|
|||||||
return inode;
|
return inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v9fs_at_to_dotl_flags- convert Linux specific AT flags to
|
||||||
|
* plan 9 AT flag.
|
||||||
|
* @flags: flags to convert
|
||||||
|
*/
|
||||||
|
static int v9fs_at_to_dotl_flags(int flags)
|
||||||
|
{
|
||||||
|
int rflags = 0;
|
||||||
|
if (flags & AT_REMOVEDIR)
|
||||||
|
rflags |= P9_DOTL_AT_REMOVEDIR;
|
||||||
|
return rflags;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* v9fs_remove - helper function to remove files and directories
|
* v9fs_remove - helper function to remove files and directories
|
||||||
* @dir: directory inode that is being deleted
|
* @dir: directory inode that is being deleted
|
||||||
@@ -558,7 +592,8 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
if (v9fs_proto_dotl(v9ses))
|
if (v9fs_proto_dotl(v9ses))
|
||||||
retval = p9_client_unlinkat(dfid, dentry->d_name.name, flags);
|
retval = p9_client_unlinkat(dfid, dentry->d_name.name,
|
||||||
|
v9fs_at_to_dotl_flags(flags));
|
||||||
if (retval == -EOPNOTSUPP) {
|
if (retval == -EOPNOTSUPP) {
|
||||||
/* Try the one based on path */
|
/* Try the one based on path */
|
||||||
v9fid = v9fs_fid_clone(dentry);
|
v9fid = v9fs_fid_clone(dentry);
|
||||||
@@ -645,13 +680,11 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
|
|||||||
P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
|
P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
err = v9fs_fid_add(dentry, fid);
|
err = v9fs_fid_add(dentry, fid);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
d_instantiate(dentry, inode);
|
||||||
return ofid;
|
return ofid;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (ofid)
|
if (ofid)
|
||||||
p9_client_clunk(ofid);
|
p9_client_clunk(ofid);
|
||||||
@@ -792,6 +825,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
|||||||
struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
struct nameidata *nameidata)
|
struct nameidata *nameidata)
|
||||||
{
|
{
|
||||||
|
struct dentry *res;
|
||||||
struct super_block *sb;
|
struct super_block *sb;
|
||||||
struct v9fs_session_info *v9ses;
|
struct v9fs_session_info *v9ses;
|
||||||
struct p9_fid *dfid, *fid;
|
struct p9_fid *dfid, *fid;
|
||||||
@@ -823,22 +857,35 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
|||||||
|
|
||||||
return ERR_PTR(result);
|
return ERR_PTR(result);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Make sure we don't use a wrong inode due to parallel
|
||||||
|
* unlink. For cached mode create calls request for new
|
||||||
|
* inode. But with cache disabled, lookup should do this.
|
||||||
|
*/
|
||||||
|
if (v9ses->cache)
|
||||||
inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
|
inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||||
|
else
|
||||||
|
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
result = PTR_ERR(inode);
|
result = PTR_ERR(inode);
|
||||||
inode = NULL;
|
inode = NULL;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = v9fs_fid_add(dentry, fid);
|
result = v9fs_fid_add(dentry, fid);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
goto error_iput;
|
goto error_iput;
|
||||||
|
|
||||||
inst_out:
|
inst_out:
|
||||||
d_add(dentry, inode);
|
/*
|
||||||
return NULL;
|
* If we had a rename on the server and a parallel lookup
|
||||||
|
* for the new name, then make sure we instantiate with
|
||||||
|
* the new name. ie look up for a/b, while on server somebody
|
||||||
|
* moved b under k and client parallely did a lookup for
|
||||||
|
* k/b.
|
||||||
|
*/
|
||||||
|
res = d_materialise_unique(dentry, inode);
|
||||||
|
if (!IS_ERR(res))
|
||||||
|
return res;
|
||||||
|
result = PTR_ERR(res);
|
||||||
error_iput:
|
error_iput:
|
||||||
iput(inode);
|
iput(inode);
|
||||||
error:
|
error:
|
||||||
@@ -1086,6 +1133,7 @@ void
|
|||||||
v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
|
v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
|
||||||
struct super_block *sb)
|
struct super_block *sb)
|
||||||
{
|
{
|
||||||
|
mode_t mode;
|
||||||
char ext[32];
|
char ext[32];
|
||||||
char tag_name[14];
|
char tag_name[14];
|
||||||
unsigned int i_nlink;
|
unsigned int i_nlink;
|
||||||
@@ -1121,31 +1169,9 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
|
|||||||
inode->i_nlink = i_nlink;
|
inode->i_nlink = i_nlink;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inode->i_mode = p9mode2unixmode(v9ses, stat->mode);
|
mode = stat->mode & S_IALLUGO;
|
||||||
if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
|
mode |= inode->i_mode & ~S_IALLUGO;
|
||||||
char type = 0;
|
inode->i_mode = mode;
|
||||||
int major = -1;
|
|
||||||
int minor = -1;
|
|
||||||
|
|
||||||
strncpy(ext, stat->extension, sizeof(ext));
|
|
||||||
sscanf(ext, "%c %u %u", &type, &major, &minor);
|
|
||||||
switch (type) {
|
|
||||||
case 'c':
|
|
||||||
inode->i_mode &= ~S_IFBLK;
|
|
||||||
inode->i_mode |= S_IFCHR;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
P9_DPRINTK(P9_DEBUG_ERROR,
|
|
||||||
"Unknown special type %c %s\n", type,
|
|
||||||
stat->extension);
|
|
||||||
};
|
|
||||||
inode->i_rdev = MKDEV(major, minor);
|
|
||||||
init_special_inode(inode, inode->i_mode, inode->i_rdev);
|
|
||||||
} else
|
|
||||||
inode->i_rdev = 0;
|
|
||||||
|
|
||||||
i_size_write(inode, stat->length);
|
i_size_write(inode, stat->length);
|
||||||
|
|
||||||
/* not real number of blocks, but 512 byte ones ... */
|
/* not real number of blocks, but 512 byte ones ... */
|
||||||
@@ -1411,6 +1437,8 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
|
|||||||
|
|
||||||
int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
|
int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
|
||||||
{
|
{
|
||||||
|
int umode;
|
||||||
|
dev_t rdev;
|
||||||
loff_t i_size;
|
loff_t i_size;
|
||||||
struct p9_wstat *st;
|
struct p9_wstat *st;
|
||||||
struct v9fs_session_info *v9ses;
|
struct v9fs_session_info *v9ses;
|
||||||
@@ -1419,6 +1447,12 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
|
|||||||
st = p9_client_stat(fid);
|
st = p9_client_stat(fid);
|
||||||
if (IS_ERR(st))
|
if (IS_ERR(st))
|
||||||
return PTR_ERR(st);
|
return PTR_ERR(st);
|
||||||
|
/*
|
||||||
|
* Don't update inode if the file type is different
|
||||||
|
*/
|
||||||
|
umode = p9mode2unixmode(v9ses, st, &rdev);
|
||||||
|
if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
|
||||||
|
goto out;
|
||||||
|
|
||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
/*
|
/*
|
||||||
@@ -1430,6 +1464,7 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
|
|||||||
if (v9ses->cache)
|
if (v9ses->cache)
|
||||||
inode->i_size = i_size;
|
inode->i_size = i_size;
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
|
out:
|
||||||
p9stat_free(st);
|
p9stat_free(st);
|
||||||
kfree(st);
|
kfree(st);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -153,7 +153,8 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
|
|||||||
* later.
|
* later.
|
||||||
*/
|
*/
|
||||||
inode->i_ino = i_ino;
|
inode->i_ino = i_ino;
|
||||||
retval = v9fs_init_inode(v9ses, inode, st->st_mode);
|
retval = v9fs_init_inode(v9ses, inode,
|
||||||
|
st->st_mode, new_decode_dev(st->st_rdev));
|
||||||
if (retval)
|
if (retval)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@@ -190,6 +191,58 @@ v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
|
|||||||
return inode;
|
return inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct dotl_openflag_map {
|
||||||
|
int open_flag;
|
||||||
|
int dotl_flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int v9fs_mapped_dotl_flags(int flags)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int rflags = 0;
|
||||||
|
struct dotl_openflag_map dotl_oflag_map[] = {
|
||||||
|
{ O_CREAT, P9_DOTL_CREATE },
|
||||||
|
{ O_EXCL, P9_DOTL_EXCL },
|
||||||
|
{ O_NOCTTY, P9_DOTL_NOCTTY },
|
||||||
|
{ O_TRUNC, P9_DOTL_TRUNC },
|
||||||
|
{ O_APPEND, P9_DOTL_APPEND },
|
||||||
|
{ O_NONBLOCK, P9_DOTL_NONBLOCK },
|
||||||
|
{ O_DSYNC, P9_DOTL_DSYNC },
|
||||||
|
{ FASYNC, P9_DOTL_FASYNC },
|
||||||
|
{ O_DIRECT, P9_DOTL_DIRECT },
|
||||||
|
{ O_LARGEFILE, P9_DOTL_LARGEFILE },
|
||||||
|
{ O_DIRECTORY, P9_DOTL_DIRECTORY },
|
||||||
|
{ O_NOFOLLOW, P9_DOTL_NOFOLLOW },
|
||||||
|
{ O_NOATIME, P9_DOTL_NOATIME },
|
||||||
|
{ O_CLOEXEC, P9_DOTL_CLOEXEC },
|
||||||
|
{ O_SYNC, P9_DOTL_SYNC},
|
||||||
|
};
|
||||||
|
for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) {
|
||||||
|
if (flags & dotl_oflag_map[i].open_flag)
|
||||||
|
rflags |= dotl_oflag_map[i].dotl_flag;
|
||||||
|
}
|
||||||
|
return rflags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v9fs_open_to_dotl_flags- convert Linux specific open flags to
|
||||||
|
* plan 9 open flag.
|
||||||
|
* @flags: flags to convert
|
||||||
|
*/
|
||||||
|
int v9fs_open_to_dotl_flags(int flags)
|
||||||
|
{
|
||||||
|
int rflags = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY
|
||||||
|
* and P9_DOTL_NOACCESS
|
||||||
|
*/
|
||||||
|
rflags |= flags & O_ACCMODE;
|
||||||
|
rflags |= v9fs_mapped_dotl_flags(flags);
|
||||||
|
|
||||||
|
return rflags;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
|
* v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
|
||||||
* @dir: directory inode that is being created
|
* @dir: directory inode that is being created
|
||||||
@@ -258,7 +311,8 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
|
|||||||
"Failed to get acl values in creat %d\n", err);
|
"Failed to get acl values in creat %d\n", err);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid);
|
err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags),
|
||||||
|
mode, gid, &qid);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
P9_DPRINTK(P9_DEBUG_VFS,
|
P9_DPRINTK(P9_DEBUG_VFS,
|
||||||
"p9_client_open_dotl failed in creat %d\n",
|
"p9_client_open_dotl failed in creat %d\n",
|
||||||
@@ -281,10 +335,10 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
|
|||||||
P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
|
P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
err = v9fs_fid_add(dentry, fid);
|
err = v9fs_fid_add(dentry, fid);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
d_instantiate(dentry, inode);
|
||||||
|
|
||||||
/* Now set the ACL based on the default value */
|
/* Now set the ACL based on the default value */
|
||||||
v9fs_set_create_acl(dentry, &dacl, &pacl);
|
v9fs_set_create_acl(dentry, &dacl, &pacl);
|
||||||
@@ -403,10 +457,10 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
|
|||||||
err);
|
err);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
err = v9fs_fid_add(dentry, fid);
|
err = v9fs_fid_add(dentry, fid);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
d_instantiate(dentry, inode);
|
||||||
fid = NULL;
|
fid = NULL;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@@ -414,7 +468,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
|
|||||||
* inode with stat. We need to get an inode
|
* inode with stat. We need to get an inode
|
||||||
* so that we can set the acl with dentry
|
* so that we can set the acl with dentry
|
||||||
*/
|
*/
|
||||||
inode = v9fs_get_inode(dir->i_sb, mode);
|
inode = v9fs_get_inode(dir->i_sb, mode, 0);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
goto error;
|
goto error;
|
||||||
@@ -540,6 +594,7 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
|
|||||||
void
|
void
|
||||||
v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
|
v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
|
||||||
{
|
{
|
||||||
|
mode_t mode;
|
||||||
struct v9fs_inode *v9inode = V9FS_I(inode);
|
struct v9fs_inode *v9inode = V9FS_I(inode);
|
||||||
|
|
||||||
if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
|
if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
|
||||||
@@ -552,11 +607,10 @@ v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
|
|||||||
inode->i_uid = stat->st_uid;
|
inode->i_uid = stat->st_uid;
|
||||||
inode->i_gid = stat->st_gid;
|
inode->i_gid = stat->st_gid;
|
||||||
inode->i_nlink = stat->st_nlink;
|
inode->i_nlink = stat->st_nlink;
|
||||||
inode->i_mode = stat->st_mode;
|
|
||||||
inode->i_rdev = new_decode_dev(stat->st_rdev);
|
|
||||||
|
|
||||||
if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode)))
|
mode = stat->st_mode & S_IALLUGO;
|
||||||
init_special_inode(inode, inode->i_mode, inode->i_rdev);
|
mode |= inode->i_mode & ~S_IALLUGO;
|
||||||
|
inode->i_mode = mode;
|
||||||
|
|
||||||
i_size_write(inode, stat->st_size);
|
i_size_write(inode, stat->st_size);
|
||||||
inode->i_blocks = stat->st_blocks;
|
inode->i_blocks = stat->st_blocks;
|
||||||
@@ -657,14 +711,14 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
|
|||||||
err);
|
err);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
err = v9fs_fid_add(dentry, fid);
|
err = v9fs_fid_add(dentry, fid);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
d_instantiate(dentry, inode);
|
||||||
fid = NULL;
|
fid = NULL;
|
||||||
} else {
|
} else {
|
||||||
/* Not in cached mode. No need to populate inode with stat */
|
/* Not in cached mode. No need to populate inode with stat */
|
||||||
inode = v9fs_get_inode(dir->i_sb, S_IFLNK);
|
inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
goto error;
|
goto error;
|
||||||
@@ -810,17 +864,17 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
|
|||||||
err);
|
err);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
d_instantiate(dentry, inode);
|
|
||||||
err = v9fs_fid_add(dentry, fid);
|
err = v9fs_fid_add(dentry, fid);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
d_instantiate(dentry, inode);
|
||||||
fid = NULL;
|
fid = NULL;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Not in cached mode. No need to populate inode with stat.
|
* Not in cached mode. No need to populate inode with stat.
|
||||||
* socket syscall returns a fd, so we need instantiate
|
* socket syscall returns a fd, so we need instantiate
|
||||||
*/
|
*/
|
||||||
inode = v9fs_get_inode(dir->i_sb, mode);
|
inode = v9fs_get_inode(dir->i_sb, mode, rdev);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
goto error;
|
goto error;
|
||||||
@@ -886,6 +940,11 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
|
|||||||
st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
|
st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
|
||||||
if (IS_ERR(st))
|
if (IS_ERR(st))
|
||||||
return PTR_ERR(st);
|
return PTR_ERR(st);
|
||||||
|
/*
|
||||||
|
* Don't update inode if the file type is different
|
||||||
|
*/
|
||||||
|
if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
|
||||||
|
goto out;
|
||||||
|
|
||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
/*
|
/*
|
||||||
@@ -897,6 +956,7 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
|
|||||||
if (v9ses->cache)
|
if (v9ses->cache)
|
||||||
inode->i_size = i_size;
|
inode->i_size = i_size;
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
|
out:
|
||||||
kfree(st);
|
kfree(st);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
|
|||||||
else
|
else
|
||||||
sb->s_d_op = &v9fs_dentry_operations;
|
sb->s_d_op = &v9fs_dentry_operations;
|
||||||
|
|
||||||
inode = v9fs_get_inode(sb, S_IFDIR | mode);
|
inode = v9fs_get_inode(sb, S_IFDIR | mode, 0);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
retval = PTR_ERR(inode);
|
retval = PTR_ERR(inode);
|
||||||
goto release_sb;
|
goto release_sb;
|
||||||
|
|||||||
@@ -1429,6 +1429,11 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
|
|||||||
WARN_ON_ONCE(bdev->bd_holders);
|
WARN_ON_ONCE(bdev->bd_holders);
|
||||||
sync_blockdev(bdev);
|
sync_blockdev(bdev);
|
||||||
kill_bdev(bdev);
|
kill_bdev(bdev);
|
||||||
|
/* ->release can cause the old bdi to disappear,
|
||||||
|
* so must switch it out first
|
||||||
|
*/
|
||||||
|
bdev_inode_switch_bdi(bdev->bd_inode,
|
||||||
|
&default_backing_dev_info);
|
||||||
}
|
}
|
||||||
if (bdev->bd_contains == bdev) {
|
if (bdev->bd_contains == bdev) {
|
||||||
if (disk->fops->release)
|
if (disk->fops->release)
|
||||||
@@ -1442,8 +1447,6 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
|
|||||||
disk_put_part(bdev->bd_part);
|
disk_put_part(bdev->bd_part);
|
||||||
bdev->bd_part = NULL;
|
bdev->bd_part = NULL;
|
||||||
bdev->bd_disk = NULL;
|
bdev->bd_disk = NULL;
|
||||||
bdev_inode_switch_bdi(bdev->bd_inode,
|
|
||||||
&default_backing_dev_info);
|
|
||||||
if (bdev != bdev->bd_contains)
|
if (bdev != bdev->bd_contains)
|
||||||
victim = bdev->bd_contains;
|
victim = bdev->bd_contains;
|
||||||
bdev->bd_contains = NULL;
|
bdev->bd_contains = NULL;
|
||||||
|
|||||||
@@ -176,7 +176,11 @@ static inline u64 btrfs_ino(struct inode *inode)
|
|||||||
{
|
{
|
||||||
u64 ino = BTRFS_I(inode)->location.objectid;
|
u64 ino = BTRFS_I(inode)->location.objectid;
|
||||||
|
|
||||||
if (ino <= BTRFS_FIRST_FREE_OBJECTID)
|
/*
|
||||||
|
* !ino: btree_inode
|
||||||
|
* type == BTRFS_ROOT_ITEM_KEY: subvol dir
|
||||||
|
*/
|
||||||
|
if (!ino || BTRFS_I(inode)->location.type == BTRFS_ROOT_ITEM_KEY)
|
||||||
ino = inode->i_ino;
|
ino = inode->i_ino;
|
||||||
return ino;
|
return ino;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,8 +183,10 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
|
|||||||
* read from the commit root and sidestep a nasty deadlock
|
* read from the commit root and sidestep a nasty deadlock
|
||||||
* between reading the free space cache and updating the csum tree.
|
* between reading the free space cache and updating the csum tree.
|
||||||
*/
|
*/
|
||||||
if (btrfs_is_free_space_inode(root, inode))
|
if (btrfs_is_free_space_inode(root, inode)) {
|
||||||
path->search_commit_root = 1;
|
path->search_commit_root = 1;
|
||||||
|
path->skip_locking = 1;
|
||||||
|
}
|
||||||
|
|
||||||
disk_bytenr = (u64)bio->bi_sector << 9;
|
disk_bytenr = (u64)bio->bi_sector << 9;
|
||||||
if (dio)
|
if (dio)
|
||||||
|
|||||||
@@ -1075,12 +1075,6 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file,
|
|||||||
start_pos = pos & ~((u64)root->sectorsize - 1);
|
start_pos = pos & ~((u64)root->sectorsize - 1);
|
||||||
last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT;
|
last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT;
|
||||||
|
|
||||||
if (start_pos > inode->i_size) {
|
|
||||||
err = btrfs_cont_expand(inode, i_size_read(inode), start_pos);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
again:
|
again:
|
||||||
for (i = 0; i < num_pages; i++) {
|
for (i = 0; i < num_pages; i++) {
|
||||||
pages[i] = find_or_create_page(inode->i_mapping, index + i,
|
pages[i] = find_or_create_page(inode->i_mapping, index + i,
|
||||||
@@ -1338,6 +1332,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
|
|||||||
struct inode *inode = fdentry(file)->d_inode;
|
struct inode *inode = fdentry(file)->d_inode;
|
||||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||||
loff_t *ppos = &iocb->ki_pos;
|
loff_t *ppos = &iocb->ki_pos;
|
||||||
|
u64 start_pos;
|
||||||
ssize_t num_written = 0;
|
ssize_t num_written = 0;
|
||||||
ssize_t err = 0;
|
ssize_t err = 0;
|
||||||
size_t count, ocount;
|
size_t count, ocount;
|
||||||
@@ -1386,6 +1381,15 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
|
|||||||
file_update_time(file);
|
file_update_time(file);
|
||||||
BTRFS_I(inode)->sequence++;
|
BTRFS_I(inode)->sequence++;
|
||||||
|
|
||||||
|
start_pos = round_down(pos, root->sectorsize);
|
||||||
|
if (start_pos > i_size_read(inode)) {
|
||||||
|
err = btrfs_cont_expand(inode, i_size_read(inode), start_pos);
|
||||||
|
if (err) {
|
||||||
|
mutex_unlock(&inode->i_mutex);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(file->f_flags & O_DIRECT)) {
|
if (unlikely(file->f_flags & O_DIRECT)) {
|
||||||
num_written = __btrfs_direct_write(iocb, iov, nr_segs,
|
num_written = __btrfs_direct_write(iocb, iov, nr_segs,
|
||||||
pos, ppos, count, ocount);
|
pos, ppos, count, ocount);
|
||||||
|
|||||||
@@ -190,9 +190,11 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
|
|||||||
struct btrfs_path *path,
|
struct btrfs_path *path,
|
||||||
struct inode *inode)
|
struct inode *inode)
|
||||||
{
|
{
|
||||||
|
struct btrfs_block_rsv *rsv;
|
||||||
loff_t oldsize;
|
loff_t oldsize;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
rsv = trans->block_rsv;
|
||||||
trans->block_rsv = root->orphan_block_rsv;
|
trans->block_rsv = root->orphan_block_rsv;
|
||||||
ret = btrfs_block_rsv_check(trans, root,
|
ret = btrfs_block_rsv_check(trans, root,
|
||||||
root->orphan_block_rsv,
|
root->orphan_block_rsv,
|
||||||
@@ -210,6 +212,8 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
|
|||||||
*/
|
*/
|
||||||
ret = btrfs_truncate_inode_items(trans, root, inode,
|
ret = btrfs_truncate_inode_items(trans, root, inode,
|
||||||
0, BTRFS_EXTENT_DATA_KEY);
|
0, BTRFS_EXTENT_DATA_KEY);
|
||||||
|
|
||||||
|
trans->block_rsv = rsv;
|
||||||
if (ret) {
|
if (ret) {
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -1786,7 +1786,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
|
|||||||
&ordered_extent->list);
|
&ordered_extent->list);
|
||||||
|
|
||||||
ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent);
|
ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent);
|
||||||
if (!ret) {
|
if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
|
||||||
ret = btrfs_update_inode(trans, root, inode);
|
ret = btrfs_update_inode(trans, root, inode);
|
||||||
BUG_ON(ret);
|
BUG_ON(ret);
|
||||||
}
|
}
|
||||||
@@ -3510,15 +3510,19 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
|
|||||||
err = btrfs_drop_extents(trans, inode, cur_offset,
|
err = btrfs_drop_extents(trans, inode, cur_offset,
|
||||||
cur_offset + hole_size,
|
cur_offset + hole_size,
|
||||||
&hint_byte, 1);
|
&hint_byte, 1);
|
||||||
if (err)
|
if (err) {
|
||||||
|
btrfs_end_transaction(trans, root);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
err = btrfs_insert_file_extent(trans, root,
|
err = btrfs_insert_file_extent(trans, root,
|
||||||
btrfs_ino(inode), cur_offset, 0,
|
btrfs_ino(inode), cur_offset, 0,
|
||||||
0, hole_size, 0, hole_size,
|
0, hole_size, 0, hole_size,
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (err)
|
if (err) {
|
||||||
|
btrfs_end_transaction(trans, root);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
btrfs_drop_extent_cache(inode, hole_start,
|
btrfs_drop_extent_cache(inode, hole_start,
|
||||||
last_byte - 1, 0);
|
last_byte - 1, 0);
|
||||||
@@ -3952,7 +3956,6 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
|
|||||||
struct btrfs_root *root, int *new)
|
struct btrfs_root *root, int *new)
|
||||||
{
|
{
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
int bad_inode = 0;
|
|
||||||
|
|
||||||
inode = btrfs_iget_locked(s, location->objectid, root);
|
inode = btrfs_iget_locked(s, location->objectid, root);
|
||||||
if (!inode)
|
if (!inode)
|
||||||
@@ -3968,14 +3971,11 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
|
|||||||
if (new)
|
if (new)
|
||||||
*new = 1;
|
*new = 1;
|
||||||
} else {
|
} else {
|
||||||
bad_inode = 1;
|
unlock_new_inode(inode);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bad_inode) {
|
|
||||||
iput(inode);
|
iput(inode);
|
||||||
inode = ERR_PTR(-ESTALE);
|
inode = ERR_PTR(-ESTALE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return inode;
|
return inode;
|
||||||
}
|
}
|
||||||
@@ -5823,7 +5823,7 @@ again:
|
|||||||
|
|
||||||
add_pending_csums(trans, inode, ordered->file_offset, &ordered->list);
|
add_pending_csums(trans, inode, ordered->file_offset, &ordered->list);
|
||||||
ret = btrfs_ordered_update_i_size(inode, 0, ordered);
|
ret = btrfs_ordered_update_i_size(inode, 0, ordered);
|
||||||
if (!ret)
|
if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags))
|
||||||
btrfs_update_inode(trans, root, inode);
|
btrfs_update_inode(trans, root, inode);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out_unlock:
|
out_unlock:
|
||||||
|
|||||||
@@ -2220,6 +2220,12 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
|||||||
!IS_ALIGNED(destoff, bs))
|
!IS_ALIGNED(destoff, bs))
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
|
if (destoff > inode->i_size) {
|
||||||
|
ret = btrfs_cont_expand(inode, inode->i_size, destoff);
|
||||||
|
if (ret)
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
/* do any pending delalloc/csum calc on src, one way or
|
/* do any pending delalloc/csum calc on src, one way or
|
||||||
another, and lock file content */
|
another, and lock file content */
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -2325,14 +2331,21 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
|||||||
|
|
||||||
if (type == BTRFS_FILE_EXTENT_REG ||
|
if (type == BTRFS_FILE_EXTENT_REG ||
|
||||||
type == BTRFS_FILE_EXTENT_PREALLOC) {
|
type == BTRFS_FILE_EXTENT_PREALLOC) {
|
||||||
|
/*
|
||||||
|
* a | --- range to clone ---| b
|
||||||
|
* | ------------- extent ------------- |
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* substract range b */
|
||||||
|
if (key.offset + datal > off + len)
|
||||||
|
datal = off + len - key.offset;
|
||||||
|
|
||||||
|
/* substract range a */
|
||||||
if (off > key.offset) {
|
if (off > key.offset) {
|
||||||
datao += off - key.offset;
|
datao += off - key.offset;
|
||||||
datal -= off - key.offset;
|
datal -= off - key.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.offset + datal > off + len)
|
|
||||||
datal = off + len - key.offset;
|
|
||||||
|
|
||||||
ret = btrfs_drop_extents(trans, inode,
|
ret = btrfs_drop_extents(trans, inode,
|
||||||
new_key.offset,
|
new_key.offset,
|
||||||
new_key.offset + datal,
|
new_key.offset + datal,
|
||||||
|
|||||||
@@ -884,6 +884,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
|
|||||||
struct btrfs_root *tree_root = fs_info->tree_root;
|
struct btrfs_root *tree_root = fs_info->tree_root;
|
||||||
struct btrfs_root *root = pending->root;
|
struct btrfs_root *root = pending->root;
|
||||||
struct btrfs_root *parent_root;
|
struct btrfs_root *parent_root;
|
||||||
|
struct btrfs_block_rsv *rsv;
|
||||||
struct inode *parent_inode;
|
struct inode *parent_inode;
|
||||||
struct dentry *parent;
|
struct dentry *parent;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
@@ -895,6 +896,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
|
|||||||
u64 objectid;
|
u64 objectid;
|
||||||
u64 root_flags;
|
u64 root_flags;
|
||||||
|
|
||||||
|
rsv = trans->block_rsv;
|
||||||
|
|
||||||
new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
|
new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
|
||||||
if (!new_root_item) {
|
if (!new_root_item) {
|
||||||
pending->error = -ENOMEM;
|
pending->error = -ENOMEM;
|
||||||
@@ -1002,6 +1005,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
|
|||||||
btrfs_orphan_post_snapshot(trans, pending);
|
btrfs_orphan_post_snapshot(trans, pending);
|
||||||
fail:
|
fail:
|
||||||
kfree(new_root_item);
|
kfree(new_root_item);
|
||||||
|
trans->block_rsv = rsv;
|
||||||
btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1);
|
btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,12 @@ static int do_setxattr(struct btrfs_trans_handle *trans,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
btrfs_release_path(path);
|
btrfs_release_path(path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* remove the attribute
|
||||||
|
*/
|
||||||
|
if (!value)
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
again:
|
again:
|
||||||
@@ -158,6 +164,9 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @value: "" makes the attribute to empty, NULL removes it
|
||||||
|
*/
|
||||||
int __btrfs_setxattr(struct btrfs_trans_handle *trans,
|
int __btrfs_setxattr(struct btrfs_trans_handle *trans,
|
||||||
struct inode *inode, const char *name,
|
struct inode *inode, const char *name,
|
||||||
const void *value, size_t size, int flags)
|
const void *value, size_t size, int flags)
|
||||||
|
|||||||
@@ -1595,7 +1595,7 @@ static int set_request_path_attr(struct inode *rinode, struct dentry *rdentry,
|
|||||||
r = build_dentry_path(rdentry, ppath, pathlen, ino, freepath);
|
r = build_dentry_path(rdentry, ppath, pathlen, ino, freepath);
|
||||||
dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen,
|
dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen,
|
||||||
*ppath);
|
*ppath);
|
||||||
} else if (rpath) {
|
} else if (rpath || rino) {
|
||||||
*ino = rino;
|
*ino = rino;
|
||||||
*ppath = rpath;
|
*ppath = rpath;
|
||||||
*pathlen = strlen(rpath);
|
*pathlen = strlen(rpath);
|
||||||
|
|||||||
@@ -813,8 +813,8 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type,
|
|||||||
fsc = create_fs_client(fsopt, opt);
|
fsc = create_fs_client(fsopt, opt);
|
||||||
if (IS_ERR(fsc)) {
|
if (IS_ERR(fsc)) {
|
||||||
res = ERR_CAST(fsc);
|
res = ERR_CAST(fsc);
|
||||||
kfree(fsopt);
|
destroy_mount_options(fsopt);
|
||||||
kfree(opt);
|
ceph_destroy_options(opt);
|
||||||
goto out_final;
|
goto out_final;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -258,10 +258,14 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
|
|||||||
forget->forget_one.nlookup = nlookup;
|
forget->forget_one.nlookup = nlookup;
|
||||||
|
|
||||||
spin_lock(&fc->lock);
|
spin_lock(&fc->lock);
|
||||||
|
if (fc->connected) {
|
||||||
fc->forget_list_tail->next = forget;
|
fc->forget_list_tail->next = forget;
|
||||||
fc->forget_list_tail = forget;
|
fc->forget_list_tail = forget;
|
||||||
wake_up(&fc->waitq);
|
wake_up(&fc->waitq);
|
||||||
kill_fasync(&fc->fasync, SIGIO, POLL_IN);
|
kill_fasync(&fc->fasync, SIGIO, POLL_IN);
|
||||||
|
} else {
|
||||||
|
kfree(forget);
|
||||||
|
}
|
||||||
spin_unlock(&fc->lock);
|
spin_unlock(&fc->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user