diff options
267 files changed, 5357 insertions, 2184 deletions
diff --git a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus index c2a270b45b03..833fd59926a7 100644 --- a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus +++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus | |||
| @@ -8,3 +8,41 @@ Description: The integer value of this attribute ranges from 0-4. | |||
| 8 | When written, this file sets the number of the startup profile | 8 | When written, this file sets the number of the startup profile |
| 9 | and the mouse activates this profile immediately. | 9 | and the mouse activates this profile immediately. |
| 10 | Please use actual_profile, it does the same thing. | 10 | Please use actual_profile, it does the same thing. |
| 11 | Users: http://roccat.sourceforge.net | ||
| 12 | |||
| 13 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version | ||
| 14 | Date: October 2010 | ||
| 15 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 16 | Description: When read, this file returns the raw integer version number of the | ||
| 17 | firmware reported by the mouse. Using the integer value eases | ||
| 18 | further usage in other programs. To receive the real version | ||
| 19 | number the decimal point has to be shifted 2 positions to the | ||
| 20 | left. E.g. a returned value of 121 means 1.21 | ||
| 21 | This file is readonly. | ||
| 22 | Please read binary attribute info which contains firmware version. | ||
| 23 | Users: http://roccat.sourceforge.net | ||
| 24 | |||
| 25 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_buttons | ||
| 26 | Date: August 2010 | ||
| 27 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 28 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 29 | press of a button. A profile is split in settings and buttons. | ||
| 30 | profile_buttons holds information about button layout. | ||
| 31 | When read, these files return the respective profile buttons. | ||
| 32 | The returned data is 77 bytes in size. | ||
| 33 | This file is readonly. | ||
| 34 | Write control to select profile and read profile_buttons instead. | ||
| 35 | Users: http://roccat.sourceforge.net | ||
| 36 | |||
| 37 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_settings | ||
| 38 | Date: August 2010 | ||
| 39 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 40 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 41 | press of a button. A profile is split in settings and buttons. | ||
| 42 | profile_settings holds information like resolution, sensitivity | ||
| 43 | and light effects. | ||
| 44 | When read, these files return the respective profile settings. | ||
| 45 | The returned data is 43 bytes in size. | ||
| 46 | This file is readonly. | ||
| 47 | Write control to select profile and read profile_settings instead. | ||
| 48 | Users: http://roccat.sourceforge.net \ No newline at end of file | ||
diff --git a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-kovaplus b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-kovaplus new file mode 100644 index 000000000000..4a98e02b6c6a --- /dev/null +++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-kovaplus | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_cpi | ||
| 2 | Date: January 2011 | ||
| 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 4 | Description: The integer value of this attribute ranges from 1-4. | ||
| 5 | When read, this attribute returns the number of the active | ||
| 6 | cpi level. | ||
| 7 | This file is readonly. | ||
| 8 | Has never been used. If bookkeeping is done, it's done in userland tools. | ||
| 9 | Users: http://roccat.sourceforge.net | ||
| 10 | |||
| 11 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_x | ||
| 12 | Date: January 2011 | ||
| 13 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 14 | Description: The integer value of this attribute ranges from 1-10. | ||
| 15 | When read, this attribute returns the number of the actual | ||
| 16 | sensitivity in x direction. | ||
| 17 | This file is readonly. | ||
| 18 | Has never been used. If bookkeeping is done, it's done in userland tools. | ||
| 19 | Users: http://roccat.sourceforge.net | ||
| 20 | |||
| 21 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_y | ||
| 22 | Date: January 2011 | ||
| 23 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 24 | Description: The integer value of this attribute ranges from 1-10. | ||
| 25 | When read, this attribute returns the number of the actual | ||
| 26 | sensitivity in y direction. | ||
| 27 | This file is readonly. | ||
| 28 | Has never been used. If bookkeeping is done, it's done in userland tools. | ||
| 29 | Users: http://roccat.sourceforge.net | ||
| 30 | |||
| 31 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/firmware_version | ||
| 32 | Date: January 2011 | ||
| 33 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 34 | Description: When read, this file returns the raw integer version number of the | ||
| 35 | firmware reported by the mouse. Using the integer value eases | ||
| 36 | further usage in other programs. To receive the real version | ||
| 37 | number the decimal point has to be shifted 2 positions to the | ||
| 38 | left. E.g. a returned value of 121 means 1.21 | ||
| 39 | This file is readonly. | ||
| 40 | Obsoleted by binary sysfs attribute "info". | ||
| 41 | Users: http://roccat.sourceforge.net | ||
| 42 | |||
| 43 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_buttons | ||
| 44 | Date: January 2011 | ||
| 45 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 46 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 47 | press of a button. A profile is split in settings and buttons. | ||
| 48 | profile_buttons holds information about button layout. | ||
| 49 | When read, these files return the respective profile buttons. | ||
| 50 | The returned data is 23 bytes in size. | ||
| 51 | This file is readonly. | ||
| 52 | Write control to select profile and read profile_buttons instead. | ||
| 53 | Users: http://roccat.sourceforge.net | ||
| 54 | |||
| 55 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_settings | ||
| 56 | Date: January 2011 | ||
| 57 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 58 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 59 | press of a button. A profile is split in settings and buttons. | ||
| 60 | profile_settings holds information like resolution, sensitivity | ||
| 61 | and light effects. | ||
| 62 | When read, these files return the respective profile settings. | ||
| 63 | The returned data is 16 bytes in size. | ||
| 64 | This file is readonly. | ||
| 65 | Write control to select profile and read profile_settings instead. | ||
| 66 | Users: http://roccat.sourceforge.net | ||
diff --git a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra new file mode 100644 index 000000000000..87ac87e9556d --- /dev/null +++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_cpi | ||
| 2 | Date: August 2010 | ||
| 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 4 | Description: It is possible to switch the cpi setting of the mouse with the | ||
| 5 | press of a button. | ||
| 6 | When read, this file returns the raw number of the actual cpi | ||
| 7 | setting reported by the mouse. This number has to be further | ||
| 8 | processed to receive the real dpi value. | ||
| 9 | |||
| 10 | VALUE DPI | ||
| 11 | 1 400 | ||
| 12 | 2 800 | ||
| 13 | 4 1600 | ||
| 14 | |||
| 15 | This file is readonly. | ||
| 16 | Has never been used. If bookkeeping is done, it's done in userland tools. | ||
| 17 | Users: http://roccat.sourceforge.net | ||
| 18 | |||
| 19 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_profile | ||
| 20 | Date: August 2010 | ||
| 21 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 22 | Description: When read, this file returns the number of the actual profile in | ||
| 23 | range 0-4. | ||
| 24 | This file is readonly. | ||
| 25 | Please use binary attribute "settings" which provides this information. | ||
| 26 | Users: http://roccat.sourceforge.net | ||
| 27 | |||
| 28 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/firmware_version | ||
| 29 | Date: August 2010 | ||
| 30 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 31 | Description: When read, this file returns the raw integer version number of the | ||
| 32 | firmware reported by the mouse. Using the integer value eases | ||
| 33 | further usage in other programs. To receive the real version | ||
| 34 | number the decimal point has to be shifted 2 positions to the | ||
| 35 | left. E.g. a returned value of 138 means 1.38 | ||
| 36 | This file is readonly. | ||
| 37 | Please use binary attribute "info" which provides this information. | ||
| 38 | Users: http://roccat.sourceforge.net | ||
| 39 | |||
| 40 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_buttons | ||
| 41 | Date: August 2010 | ||
| 42 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 43 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 44 | press of a button. A profile is split in settings and buttons. | ||
| 45 | profile_buttons holds information about button layout. | ||
| 46 | When read, these files return the respective profile buttons. | ||
| 47 | The returned data is 19 bytes in size. | ||
| 48 | This file is readonly. | ||
| 49 | Write control to select profile and read profile_buttons instead. | ||
| 50 | Users: http://roccat.sourceforge.net | ||
| 51 | |||
| 52 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_settings | ||
| 53 | Date: August 2010 | ||
| 54 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 55 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 56 | press of a button. A profile is split in settings and buttons. | ||
| 57 | profile_settings holds information like resolution, sensitivity | ||
| 58 | and light effects. | ||
| 59 | When read, these files return the respective profile settings. | ||
| 60 | The returned data is 13 bytes in size. | ||
| 61 | This file is readonly. | ||
| 62 | Write control to select profile and read profile_settings instead. | ||
| 63 | Users: http://roccat.sourceforge.net | ||
| 64 | |||
| 65 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/startup_profile | ||
| 66 | Date: August 2010 | ||
| 67 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 68 | Description: The integer value of this attribute ranges from 0-4. | ||
| 69 | When read, this attribute returns the number of the profile | ||
| 70 | that's active when the mouse is powered on. | ||
| 71 | This file is readonly. | ||
| 72 | Please use binary attribute "settings" which provides this information. | ||
| 73 | Users: http://roccat.sourceforge.net | ||
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku b/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku index 189dc43891bf..9eca5a182e64 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku | |||
| @@ -117,6 +117,14 @@ Description: When written, this file lets one store macros with max 500 | |||
| 117 | which profile and key to read. | 117 | which profile and key to read. |
| 118 | Users: http://roccat.sourceforge.net | 118 | Users: http://roccat.sourceforge.net |
| 119 | 119 | ||
| 120 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/isku/roccatisku<minor>/reset | ||
| 121 | Date: November 2012 | ||
| 122 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 123 | Description: When written, this file lets one reset the device. | ||
| 124 | The data has to be 3 bytes long. | ||
| 125 | This file is writeonly. | ||
| 126 | Users: http://roccat.sourceforge.net | ||
| 127 | |||
| 120 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/isku/roccatisku<minor>/control | 128 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/isku/roccatisku<minor>/control |
| 121 | Date: June 2011 | 129 | Date: June 2011 |
| 122 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 130 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus index 65e6e5dd67e8..7bd776f9c3c7 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus | |||
| @@ -9,15 +9,12 @@ Description: The integer value of this attribute ranges from 0-4. | |||
| 9 | and the mouse activates this profile immediately. | 9 | and the mouse activates this profile immediately. |
| 10 | Users: http://roccat.sourceforge.net | 10 | Users: http://roccat.sourceforge.net |
| 11 | 11 | ||
| 12 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version | 12 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/info |
| 13 | Date: October 2010 | 13 | Date: November 2012 |
| 14 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 14 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
| 15 | Description: When read, this file returns the raw integer version number of the | 15 | Description: When read, this file returns general data like firmware version. |
| 16 | firmware reported by the mouse. Using the integer value eases | 16 | When written, the device can be reset. |
| 17 | further usage in other programs. To receive the real version | 17 | The data is 8 bytes long. |
| 18 | number the decimal point has to be shifted 2 positions to the | ||
| 19 | left. E.g. a returned value of 121 means 1.21 | ||
| 20 | This file is readonly. | ||
| 21 | Users: http://roccat.sourceforge.net | 18 | Users: http://roccat.sourceforge.net |
| 22 | 19 | ||
| 23 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/macro | 20 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/macro |
| @@ -42,18 +39,8 @@ Description: The mouse can store 5 profiles which can be switched by the | |||
| 42 | The mouse will reject invalid data. | 39 | The mouse will reject invalid data. |
| 43 | Which profile to write is determined by the profile number | 40 | Which profile to write is determined by the profile number |
| 44 | contained in the data. | 41 | contained in the data. |
| 45 | This file is writeonly. | 42 | Before reading this file, control has to be written to select |
| 46 | Users: http://roccat.sourceforge.net | 43 | which profile to read. |
| 47 | |||
| 48 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_buttons | ||
| 49 | Date: August 2010 | ||
| 50 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 51 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 52 | press of a button. A profile is split in settings and buttons. | ||
| 53 | profile_buttons holds information about button layout. | ||
| 54 | When read, these files return the respective profile buttons. | ||
| 55 | The returned data is 77 bytes in size. | ||
| 56 | This file is readonly. | ||
| 57 | Users: http://roccat.sourceforge.net | 44 | Users: http://roccat.sourceforge.net |
| 58 | 45 | ||
| 59 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_settings | 46 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_settings |
| @@ -68,19 +55,8 @@ Description: The mouse can store 5 profiles which can be switched by the | |||
| 68 | The mouse will reject invalid data. | 55 | The mouse will reject invalid data. |
| 69 | Which profile to write is determined by the profile number | 56 | Which profile to write is determined by the profile number |
| 70 | contained in the data. | 57 | contained in the data. |
| 71 | This file is writeonly. | 58 | Before reading this file, control has to be written to select |
| 72 | Users: http://roccat.sourceforge.net | 59 | which profile to read. |
| 73 | |||
| 74 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_settings | ||
| 75 | Date: August 2010 | ||
| 76 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 77 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 78 | press of a button. A profile is split in settings and buttons. | ||
| 79 | profile_settings holds information like resolution, sensitivity | ||
| 80 | and light effects. | ||
| 81 | When read, these files return the respective profile settings. | ||
| 82 | The returned data is 43 bytes in size. | ||
| 83 | This file is readonly. | ||
| 84 | Users: http://roccat.sourceforge.net | 60 | Users: http://roccat.sourceforge.net |
| 85 | 61 | ||
| 86 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/sensor | 62 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/sensor |
| @@ -104,9 +80,9 @@ What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid- | |||
| 104 | Date: October 2010 | 80 | Date: October 2010 |
| 105 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 81 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
| 106 | Description: When written a calibration process for the tracking control unit | 82 | Description: When written a calibration process for the tracking control unit |
| 107 | can be initiated/cancelled. | 83 | can be initiated/cancelled. Also lets one read/write sensor |
| 108 | The data has to be 3 bytes long. | 84 | registers. |
| 109 | This file is writeonly. | 85 | The data has to be 4 bytes long. |
| 110 | Users: http://roccat.sourceforge.net | 86 | Users: http://roccat.sourceforge.net |
| 111 | 87 | ||
| 112 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu_image | 88 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu_image |
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus index 20f937c9d84f..a10404f15a54 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus | |||
| @@ -1,12 +1,3 @@ | |||
| 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_cpi | ||
| 2 | Date: January 2011 | ||
| 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 4 | Description: The integer value of this attribute ranges from 1-4. | ||
| 5 | When read, this attribute returns the number of the active | ||
| 6 | cpi level. | ||
| 7 | This file is readonly. | ||
| 8 | Users: http://roccat.sourceforge.net | ||
| 9 | |||
| 10 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_profile | 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_profile |
| 11 | Date: January 2011 | 2 | Date: January 2011 |
| 12 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
| @@ -18,33 +9,12 @@ Description: The integer value of this attribute ranges from 0-4. | |||
| 18 | active when the mouse is powered on. | 9 | active when the mouse is powered on. |
| 19 | Users: http://roccat.sourceforge.net | 10 | Users: http://roccat.sourceforge.net |
| 20 | 11 | ||
| 21 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_x | 12 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/info |
| 22 | Date: January 2011 | 13 | Date: November 2012 |
| 23 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 14 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
| 24 | Description: The integer value of this attribute ranges from 1-10. | 15 | Description: When read, this file returns general data like firmware version. |
| 25 | When read, this attribute returns the number of the actual | 16 | When written, the device can be reset. |
| 26 | sensitivity in x direction. | 17 | The data is 6 bytes long. |
| 27 | This file is readonly. | ||
| 28 | Users: http://roccat.sourceforge.net | ||
| 29 | |||
| 30 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_y | ||
| 31 | Date: January 2011 | ||
| 32 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 33 | Description: The integer value of this attribute ranges from 1-10. | ||
| 34 | When read, this attribute returns the number of the actual | ||
| 35 | sensitivity in y direction. | ||
| 36 | This file is readonly. | ||
| 37 | Users: http://roccat.sourceforge.net | ||
| 38 | |||
| 39 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/firmware_version | ||
| 40 | Date: January 2011 | ||
| 41 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 42 | Description: When read, this file returns the raw integer version number of the | ||
| 43 | firmware reported by the mouse. Using the integer value eases | ||
| 44 | further usage in other programs. To receive the real version | ||
| 45 | number the decimal point has to be shifted 2 positions to the | ||
| 46 | left. E.g. a returned value of 121 means 1.21 | ||
| 47 | This file is readonly. | ||
| 48 | Users: http://roccat.sourceforge.net | 18 | Users: http://roccat.sourceforge.net |
| 49 | 19 | ||
| 50 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_buttons | 20 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_buttons |
| @@ -58,18 +28,8 @@ Description: The mouse can store 5 profiles which can be switched by the | |||
| 58 | The mouse will reject invalid data. | 28 | The mouse will reject invalid data. |
| 59 | Which profile to write is determined by the profile number | 29 | Which profile to write is determined by the profile number |
| 60 | contained in the data. | 30 | contained in the data. |
| 61 | This file is writeonly. | 31 | Before reading this file, control has to be written to select |
| 62 | Users: http://roccat.sourceforge.net | 32 | which profile to read. |
| 63 | |||
| 64 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_buttons | ||
| 65 | Date: January 2011 | ||
| 66 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 67 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 68 | press of a button. A profile is split in settings and buttons. | ||
| 69 | profile_buttons holds information about button layout. | ||
| 70 | When read, these files return the respective profile buttons. | ||
| 71 | The returned data is 23 bytes in size. | ||
| 72 | This file is readonly. | ||
| 73 | Users: http://roccat.sourceforge.net | 33 | Users: http://roccat.sourceforge.net |
| 74 | 34 | ||
| 75 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_settings | 35 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_settings |
| @@ -84,17 +44,6 @@ Description: The mouse can store 5 profiles which can be switched by the | |||
| 84 | The mouse will reject invalid data. | 44 | The mouse will reject invalid data. |
| 85 | Which profile to write is determined by the profile number | 45 | Which profile to write is determined by the profile number |
| 86 | contained in the data. | 46 | contained in the data. |
| 87 | This file is writeonly. | 47 | Before reading this file, control has to be written to select |
| 88 | Users: http://roccat.sourceforge.net | 48 | which profile to read. |
| 89 | |||
| 90 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_settings | ||
| 91 | Date: January 2011 | ||
| 92 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 93 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 94 | press of a button. A profile is split in settings and buttons. | ||
| 95 | profile_settings holds information like resolution, sensitivity | ||
| 96 | and light effects. | ||
| 97 | When read, these files return the respective profile settings. | ||
| 98 | The returned data is 16 bytes in size. | ||
| 99 | This file is readonly. | ||
| 100 | Users: http://roccat.sourceforge.net | 49 | Users: http://roccat.sourceforge.net |
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-lua b/Documentation/ABI/testing/sysfs-driver-hid-roccat-lua new file mode 100644 index 000000000000..31c6c4c8ba2b --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-lua | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/control | ||
| 2 | Date: October 2012 | ||
| 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 4 | Description: When written, cpi, button and light settings can be configured. | ||
| 5 | When read, actual cpi setting and sensor data are returned. | ||
| 6 | The data has to be 8 bytes long. | ||
| 7 | Users: http://roccat.sourceforge.net | ||
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra index 3f8de50e4ff1..9fa9de30d14b 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra | |||
| @@ -1,37 +1,9 @@ | |||
| 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_cpi | 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/info |
| 2 | Date: August 2010 | 2 | Date: November 2012 |
| 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 4 | Description: It is possible to switch the cpi setting of the mouse with the | ||
| 5 | press of a button. | ||
| 6 | When read, this file returns the raw number of the actual cpi | ||
| 7 | setting reported by the mouse. This number has to be further | ||
| 8 | processed to receive the real dpi value. | ||
| 9 | |||
| 10 | VALUE DPI | ||
| 11 | 1 400 | ||
| 12 | 2 800 | ||
| 13 | 4 1600 | ||
| 14 | |||
| 15 | This file is readonly. | ||
| 16 | Users: http://roccat.sourceforge.net | ||
| 17 | |||
| 18 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_profile | ||
| 19 | Date: August 2010 | ||
| 20 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
| 21 | Description: When read, this file returns the number of the actual profile in | 4 | Description: When read, this file returns general data like firmware version. |
| 22 | range 0-4. | 5 | When written, the device can be reset. |
| 23 | This file is readonly. | 6 | The data is 6 bytes long. |
| 24 | Users: http://roccat.sourceforge.net | ||
| 25 | |||
| 26 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/firmware_version | ||
| 27 | Date: August 2010 | ||
| 28 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 29 | Description: When read, this file returns the raw integer version number of the | ||
| 30 | firmware reported by the mouse. Using the integer value eases | ||
| 31 | further usage in other programs. To receive the real version | ||
| 32 | number the decimal point has to be shifted 2 positions to the | ||
| 33 | left. E.g. a returned value of 138 means 1.38 | ||
| 34 | This file is readonly. | ||
| 35 | Users: http://roccat.sourceforge.net | 7 | Users: http://roccat.sourceforge.net |
| 36 | 8 | ||
| 37 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_settings | 9 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_settings |
| @@ -46,19 +18,8 @@ Description: The mouse can store 5 profiles which can be switched by the | |||
| 46 | The mouse will reject invalid data. | 18 | The mouse will reject invalid data. |
| 47 | Which profile to write is determined by the profile number | 19 | Which profile to write is determined by the profile number |
| 48 | contained in the data. | 20 | contained in the data. |
| 49 | This file is writeonly. | 21 | Before reading this file, control has to be written to select |
| 50 | Users: http://roccat.sourceforge.net | 22 | which profile to read. |
| 51 | |||
| 52 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_settings | ||
| 53 | Date: August 2010 | ||
| 54 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 55 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 56 | press of a button. A profile is split in settings and buttons. | ||
| 57 | profile_settings holds information like resolution, sensitivity | ||
| 58 | and light effects. | ||
| 59 | When read, these files return the respective profile settings. | ||
| 60 | The returned data is 13 bytes in size. | ||
| 61 | This file is readonly. | ||
| 62 | Users: http://roccat.sourceforge.net | 23 | Users: http://roccat.sourceforge.net |
| 63 | 24 | ||
| 64 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_buttons | 25 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_buttons |
| @@ -72,27 +33,8 @@ Description: The mouse can store 5 profiles which can be switched by the | |||
| 72 | The mouse will reject invalid data. | 33 | The mouse will reject invalid data. |
| 73 | Which profile to write is determined by the profile number | 34 | Which profile to write is determined by the profile number |
| 74 | contained in the data. | 35 | contained in the data. |
| 75 | This file is writeonly. | 36 | Before reading this file, control has to be written to select |
| 76 | Users: http://roccat.sourceforge.net | 37 | which profile to read. |
| 77 | |||
| 78 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_buttons | ||
| 79 | Date: August 2010 | ||
| 80 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 81 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 82 | press of a button. A profile is split in settings and buttons. | ||
| 83 | profile_buttons holds information about button layout. | ||
| 84 | When read, these files return the respective profile buttons. | ||
| 85 | The returned data is 19 bytes in size. | ||
| 86 | This file is readonly. | ||
| 87 | Users: http://roccat.sourceforge.net | ||
| 88 | |||
| 89 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/startup_profile | ||
| 90 | Date: August 2010 | ||
| 91 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 92 | Description: The integer value of this attribute ranges from 0-4. | ||
| 93 | When read, this attribute returns the number of the profile | ||
| 94 | that's active when the mouse is powered on. | ||
| 95 | This file is readonly. | ||
| 96 | Users: http://roccat.sourceforge.net | 38 | Users: http://roccat.sourceforge.net |
| 97 | 39 | ||
| 98 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/settings | 40 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/settings |
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu b/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu index b42922cf6b1f..f1e02a98bd9d 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu | |||
| @@ -40,8 +40,8 @@ What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid- | |||
| 40 | Date: Mai 2012 | 40 | Date: Mai 2012 |
| 41 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 41 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
| 42 | Description: When read, this file returns general data like firmware version. | 42 | Description: When read, this file returns general data like firmware version. |
| 43 | When written, the device can be reset. | ||
| 43 | The data is 8 bytes long. | 44 | The data is 8 bytes long. |
| 44 | This file is readonly. | ||
| 45 | Users: http://roccat.sourceforge.net | 45 | Users: http://roccat.sourceforge.net |
| 46 | 46 | ||
| 47 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/savu/roccatsavu<minor>/macro | 47 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/savu/roccatsavu<minor>/macro |
| @@ -74,4 +74,3 @@ Description: The mouse has a Avago ADNS-3090 sensor. | |||
| 74 | This file allows reading and writing of the mouse sensors registers. | 74 | This file allows reading and writing of the mouse sensors registers. |
| 75 | The data has to be 4 bytes long. | 75 | The data has to be 4 bytes long. |
| 76 | Users: http://roccat.sourceforge.net | 76 | Users: http://roccat.sourceforge.net |
| 77 | |||
diff --git a/Documentation/arm64/memory.txt b/Documentation/arm64/memory.txt index dbbdcbba75a3..4110cca96bd6 100644 --- a/Documentation/arm64/memory.txt +++ b/Documentation/arm64/memory.txt | |||
| @@ -27,17 +27,17 @@ Start End Size Use | |||
| 27 | ----------------------------------------------------------------------- | 27 | ----------------------------------------------------------------------- |
| 28 | 0000000000000000 0000007fffffffff 512GB user | 28 | 0000000000000000 0000007fffffffff 512GB user |
| 29 | 29 | ||
| 30 | ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc | 30 | ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc |
| 31 | 31 | ||
| 32 | ffffffbbfffd0000 ffffffbcfffdffff 64KB [guard page] | 32 | ffffffbbffff0000 ffffffbbffffffff 64KB [guard page] |
| 33 | 33 | ||
| 34 | ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O space | 34 | ffffffbc00000000 ffffffbdffffffff 8GB vmemmap |
| 35 | 35 | ||
| 36 | ffffffbbffff0000 ffffffbcffffffff 64KB [guard page] | 36 | ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap] |
| 37 | 37 | ||
| 38 | ffffffbc00000000 ffffffbdffffffff 8GB vmemmap | 38 | ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space |
| 39 | 39 | ||
| 40 | ffffffbe00000000 ffffffbffbffffff ~8GB [guard, future vmmemap] | 40 | ffffffbbffff0000 ffffffbcffffffff ~2MB [guard] |
| 41 | 41 | ||
| 42 | ffffffbffc000000 ffffffbfffffffff 64MB modules | 42 | ffffffbffc000000 ffffffbfffffffff 64MB modules |
| 43 | 43 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 59203e77ce9e..ff8e763eaa50 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -3598,6 +3598,49 @@ F: drivers/hid/hid-hyperv.c | |||
| 3598 | F: drivers/net/hyperv/ | 3598 | F: drivers/net/hyperv/ |
| 3599 | F: drivers/staging/hv/ | 3599 | F: drivers/staging/hv/ |
| 3600 | 3600 | ||
| 3601 | I2C OVER PARALLEL PORT | ||
| 3602 | M: Jean Delvare <khali@linux-fr.org> | ||
| 3603 | L: linux-i2c@vger.kernel.org | ||
| 3604 | S: Maintained | ||
| 3605 | F: Documentation/i2c/busses/i2c-parport | ||
| 3606 | F: Documentation/i2c/busses/i2c-parport-light | ||
| 3607 | F: drivers/i2c/busses/i2c-parport.c | ||
| 3608 | F: drivers/i2c/busses/i2c-parport-light.c | ||
| 3609 | |||
| 3610 | I2C/SMBUS CONTROLLER DRIVERS FOR PC | ||
| 3611 | M: Jean Delvare <khali@linux-fr.org> | ||
| 3612 | L: linux-i2c@vger.kernel.org | ||
| 3613 | S: Maintained | ||
| 3614 | F: Documentation/i2c/busses/i2c-ali1535 | ||
| 3615 | F: Documentation/i2c/busses/i2c-ali1563 | ||
| 3616 | F: Documentation/i2c/busses/i2c-ali15x3 | ||
| 3617 | F: Documentation/i2c/busses/i2c-amd756 | ||
| 3618 | F: Documentation/i2c/busses/i2c-amd8111 | ||
| 3619 | F: Documentation/i2c/busses/i2c-i801 | ||
| 3620 | F: Documentation/i2c/busses/i2c-nforce2 | ||
| 3621 | F: Documentation/i2c/busses/i2c-piix4 | ||
| 3622 | F: Documentation/i2c/busses/i2c-sis5595 | ||
| 3623 | F: Documentation/i2c/busses/i2c-sis630 | ||
| 3624 | F: Documentation/i2c/busses/i2c-sis96x | ||
| 3625 | F: Documentation/i2c/busses/i2c-via | ||
| 3626 | F: Documentation/i2c/busses/i2c-viapro | ||
| 3627 | F: drivers/i2c/busses/i2c-ali1535.c | ||
| 3628 | F: drivers/i2c/busses/i2c-ali1563.c | ||
| 3629 | F: drivers/i2c/busses/i2c-ali15x3.c | ||
| 3630 | F: drivers/i2c/busses/i2c-amd756.c | ||
| 3631 | F: drivers/i2c/busses/i2c-amd756-s4882.c | ||
| 3632 | F: drivers/i2c/busses/i2c-amd8111.c | ||
| 3633 | F: drivers/i2c/busses/i2c-i801.c | ||
| 3634 | F: drivers/i2c/busses/i2c-isch.c | ||
| 3635 | F: drivers/i2c/busses/i2c-nforce2.c | ||
| 3636 | F: drivers/i2c/busses/i2c-nforce2-s4985.c | ||
| 3637 | F: drivers/i2c/busses/i2c-piix4.c | ||
| 3638 | F: drivers/i2c/busses/i2c-sis5595.c | ||
| 3639 | F: drivers/i2c/busses/i2c-sis630.c | ||
| 3640 | F: drivers/i2c/busses/i2c-sis96x.c | ||
| 3641 | F: drivers/i2c/busses/i2c-via.c | ||
| 3642 | F: drivers/i2c/busses/i2c-viapro.c | ||
| 3643 | |||
| 3601 | I2C/SMBUS STUB DRIVER | 3644 | I2C/SMBUS STUB DRIVER |
| 3602 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> | 3645 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> |
| 3603 | L: linux-i2c@vger.kernel.org | 3646 | L: linux-i2c@vger.kernel.org |
| @@ -3605,9 +3648,8 @@ S: Maintained | |||
| 3605 | F: drivers/i2c/busses/i2c-stub.c | 3648 | F: drivers/i2c/busses/i2c-stub.c |
| 3606 | 3649 | ||
| 3607 | I2C SUBSYSTEM | 3650 | I2C SUBSYSTEM |
| 3608 | M: "Jean Delvare (PC drivers, core)" <khali@linux-fr.org> | 3651 | M: Wolfram Sang <w.sang@pengutronix.de> |
| 3609 | M: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org> | 3652 | M: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org> |
| 3610 | M: "Wolfram Sang (embedded platforms)" <w.sang@pengutronix.de> | ||
| 3611 | L: linux-i2c@vger.kernel.org | 3653 | L: linux-i2c@vger.kernel.org |
| 3612 | W: http://i2c.wiki.kernel.org/ | 3654 | W: http://i2c.wiki.kernel.org/ |
| 3613 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ | 3655 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ |
| @@ -3618,6 +3660,13 @@ F: drivers/i2c/ | |||
| 3618 | F: include/linux/i2c.h | 3660 | F: include/linux/i2c.h |
| 3619 | F: include/linux/i2c-*.h | 3661 | F: include/linux/i2c-*.h |
| 3620 | 3662 | ||
| 3663 | I2C-TAOS-EVM DRIVER | ||
| 3664 | M: Jean Delvare <khali@linux-fr.org> | ||
| 3665 | L: linux-i2c@vger.kernel.org | ||
| 3666 | S: Maintained | ||
| 3667 | F: Documentation/i2c/busses/i2c-taos-evm | ||
| 3668 | F: drivers/i2c/busses/i2c-taos-evm.c | ||
| 3669 | |||
| 3621 | I2C-TINY-USB DRIVER | 3670 | I2C-TINY-USB DRIVER |
| 3622 | M: Till Harbaum <till@harbaum.org> | 3671 | M: Till Harbaum <till@harbaum.org> |
| 3623 | L: linux-i2c@vger.kernel.org | 3672 | L: linux-i2c@vger.kernel.org |
| @@ -7887,13 +7936,6 @@ M: Roger Luethi <rl@hellgate.ch> | |||
| 7887 | S: Maintained | 7936 | S: Maintained |
| 7888 | F: drivers/net/ethernet/via/via-rhine.c | 7937 | F: drivers/net/ethernet/via/via-rhine.c |
| 7889 | 7938 | ||
| 7890 | VIAPRO SMBUS DRIVER | ||
| 7891 | M: Jean Delvare <khali@linux-fr.org> | ||
| 7892 | L: linux-i2c@vger.kernel.org | ||
| 7893 | S: Maintained | ||
| 7894 | F: Documentation/i2c/busses/i2c-viapro | ||
| 7895 | F: drivers/i2c/busses/i2c-viapro.c | ||
| 7896 | |||
| 7897 | VIA SD/MMC CARD CONTROLLER DRIVER | 7939 | VIA SD/MMC CARD CONTROLLER DRIVER |
| 7898 | M: Bruce Chang <brucechang@via.com.tw> | 7940 | M: Bruce Chang <brucechang@via.com.tw> |
| 7899 | M: Harald Welte <HaraldWelte@viatech.com> | 7941 | M: Harald Welte <HaraldWelte@viatech.com> |
| @@ -1,7 +1,7 @@ | |||
| 1 | VERSION = 3 | 1 | VERSION = 3 |
| 2 | PATCHLEVEL = 7 | 2 | PATCHLEVEL = 7 |
| 3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
| 4 | EXTRAVERSION = -rc4 | 4 | EXTRAVERSION = -rc5 |
| 5 | NAME = Terrified Chipmunk | 5 | NAME = Terrified Chipmunk |
| 6 | 6 | ||
| 7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 59bcb96ac369..f57609275449 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c | |||
| @@ -166,3 +166,14 @@ void free_xenballooned_pages(int nr_pages, struct page **pages) | |||
| 166 | *pages = NULL; | 166 | *pages = NULL; |
| 167 | } | 167 | } |
| 168 | EXPORT_SYMBOL_GPL(free_xenballooned_pages); | 168 | EXPORT_SYMBOL_GPL(free_xenballooned_pages); |
| 169 | |||
| 170 | /* In the hypervisor.S file. */ | ||
| 171 | EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); | ||
| 172 | EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); | ||
| 173 | EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version); | ||
| 174 | EXPORT_SYMBOL_GPL(HYPERVISOR_console_io); | ||
| 175 | EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op); | ||
| 176 | EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op); | ||
| 177 | EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op); | ||
| 178 | EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op); | ||
| 179 | EXPORT_SYMBOL_GPL(privcmd_call); | ||
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index ef54a59a9e89..15ac18a56c93 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | config ARM64 | 1 | config ARM64 |
| 2 | def_bool y | 2 | def_bool y |
| 3 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 3 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
| 4 | select ARCH_WANT_COMPAT_IPC_PARSE_VERSION | ||
| 4 | select GENERIC_CLOCKEVENTS | 5 | select GENERIC_CLOCKEVENTS |
| 5 | select GENERIC_HARDIRQS_NO_DEPRECATED | 6 | select GENERIC_HARDIRQS_NO_DEPRECATED |
| 6 | select GENERIC_IOMAP | 7 | select GENERIC_IOMAP |
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index cf284649dfcb..07fea290d7c1 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h | |||
| @@ -25,12 +25,10 @@ | |||
| 25 | #include <asm/user.h> | 25 | #include <asm/user.h> |
| 26 | 26 | ||
| 27 | typedef unsigned long elf_greg_t; | 27 | typedef unsigned long elf_greg_t; |
| 28 | typedef unsigned long elf_freg_t[3]; | ||
| 29 | 28 | ||
| 30 | #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) | 29 | #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) |
| 31 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | 30 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; |
| 32 | 31 | typedef struct user_fpsimd_state elf_fpregset_t; | |
| 33 | typedef struct user_fp elf_fpregset_t; | ||
| 34 | 32 | ||
| 35 | #define EM_AARCH64 183 | 33 | #define EM_AARCH64 183 |
| 36 | 34 | ||
| @@ -87,7 +85,6 @@ typedef struct user_fp elf_fpregset_t; | |||
| 87 | #define R_AARCH64_MOVW_PREL_G2_NC 292 | 85 | #define R_AARCH64_MOVW_PREL_G2_NC 292 |
| 88 | #define R_AARCH64_MOVW_PREL_G3 293 | 86 | #define R_AARCH64_MOVW_PREL_G3 293 |
| 89 | 87 | ||
| 90 | |||
| 91 | /* | 88 | /* |
| 92 | * These are used to set parameters in the core dumps. | 89 | * These are used to set parameters in the core dumps. |
| 93 | */ | 90 | */ |
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index b42fab9f62a9..c43b4ac13008 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h | |||
| @@ -25,9 +25,8 @@ | |||
| 25 | * - FPSR and FPCR | 25 | * - FPSR and FPCR |
| 26 | * - 32 128-bit data registers | 26 | * - 32 128-bit data registers |
| 27 | * | 27 | * |
| 28 | * Note that user_fp forms a prefix of this structure, which is relied | 28 | * Note that user_fpsimd forms a prefix of this structure, which is |
| 29 | * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must | 29 | * relied upon in the ptrace FP/SIMD accessors. |
| 30 | * form a prefix of struct fpsimd_state. | ||
| 31 | */ | 30 | */ |
| 32 | struct fpsimd_state { | 31 | struct fpsimd_state { |
| 33 | union { | 32 | union { |
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 74a2a7d304a9..54f6116697f7 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h | |||
| @@ -114,7 +114,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) | |||
| 114 | * I/O port access primitives. | 114 | * I/O port access primitives. |
| 115 | */ | 115 | */ |
| 116 | #define IO_SPACE_LIMIT 0xffff | 116 | #define IO_SPACE_LIMIT 0xffff |
| 117 | #define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL) | 117 | #define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M)) |
| 118 | 118 | ||
| 119 | static inline u8 inb(unsigned long addr) | 119 | static inline u8 inb(unsigned long addr) |
| 120 | { | 120 | { |
| @@ -225,9 +225,9 @@ extern void __iounmap(volatile void __iomem *addr); | |||
| 225 | #define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) | 225 | #define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) |
| 226 | #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) | 226 | #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) |
| 227 | 227 | ||
| 228 | #define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) | 228 | #define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) |
| 229 | #define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) | 229 | #define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) |
| 230 | #define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC) | 230 | #define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC)) |
| 231 | #define iounmap __iounmap | 231 | #define iounmap __iounmap |
| 232 | 232 | ||
| 233 | #define ARCH_HAS_IOREMAP_WC | 233 | #define ARCH_HAS_IOREMAP_WC |
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 5d810044feda..77f696c14339 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h | |||
| @@ -43,6 +43,8 @@ | |||
| 43 | #else | 43 | #else |
| 44 | #define STACK_TOP STACK_TOP_MAX | 44 | #define STACK_TOP STACK_TOP_MAX |
| 45 | #endif /* CONFIG_COMPAT */ | 45 | #endif /* CONFIG_COMPAT */ |
| 46 | |||
| 47 | #define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK | ||
| 46 | #endif /* __KERNEL__ */ | 48 | #endif /* __KERNEL__ */ |
| 47 | 49 | ||
| 48 | struct debug_info { | 50 | struct debug_info { |
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index 63f853f8b718..68aff2816e86 100644 --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | */ | 15 | */ |
| 16 | #ifdef CONFIG_COMPAT | 16 | #ifdef CONFIG_COMPAT |
| 17 | #define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION | ||
| 18 | #define __ARCH_WANT_COMPAT_STAT64 | 17 | #define __ARCH_WANT_COMPAT_STAT64 |
| 19 | #define __ARCH_WANT_SYS_GETHOSTNAME | 18 | #define __ARCH_WANT_SYS_GETHOSTNAME |
| 20 | #define __ARCH_WANT_SYS_PAUSE | 19 | #define __ARCH_WANT_SYS_PAUSE |
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index ecbf2d81ec5c..c76c7241125b 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c | |||
| @@ -613,17 +613,11 @@ enum armv8_pmuv3_perf_types { | |||
| 613 | ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19, | 613 | ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19, |
| 614 | ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A, | 614 | ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A, |
| 615 | ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D, | 615 | ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D, |
| 616 | |||
| 617 | /* | ||
| 618 | * This isn't an architected event. | ||
| 619 | * We detect this event number and use the cycle counter instead. | ||
| 620 | */ | ||
| 621 | ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF, | ||
| 622 | }; | 616 | }; |
| 623 | 617 | ||
| 624 | /* PMUv3 HW events mapping. */ | 618 | /* PMUv3 HW events mapping. */ |
| 625 | static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { | 619 | static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { |
| 626 | [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, | 620 | [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES, |
| 627 | [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED, | 621 | [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED, |
| 628 | [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS, | 622 | [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS, |
| 629 | [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL, | 623 | [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL, |
| @@ -1106,7 +1100,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc, | |||
| 1106 | unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT; | 1100 | unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT; |
| 1107 | 1101 | ||
| 1108 | /* Always place a cycle counter into the cycle counter. */ | 1102 | /* Always place a cycle counter into the cycle counter. */ |
| 1109 | if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) { | 1103 | if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) { |
| 1110 | if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) | 1104 | if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) |
| 1111 | return -EAGAIN; | 1105 | return -EAGAIN; |
| 1112 | 1106 | ||
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index f22965ea1cfc..e04cebdbb47f 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c | |||
| @@ -310,24 +310,6 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
| 310 | } | 310 | } |
| 311 | 311 | ||
| 312 | /* | 312 | /* |
| 313 | * Fill in the task's elfregs structure for a core dump. | ||
| 314 | */ | ||
| 315 | int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs) | ||
| 316 | { | ||
| 317 | elf_core_copy_regs(elfregs, task_pt_regs(t)); | ||
| 318 | return 1; | ||
| 319 | } | ||
| 320 | |||
| 321 | /* | ||
| 322 | * fill in the fpe structure for a core dump... | ||
| 323 | */ | ||
| 324 | int dump_fpu (struct pt_regs *regs, struct user_fp *fp) | ||
| 325 | { | ||
| 326 | return 0; | ||
| 327 | } | ||
| 328 | EXPORT_SYMBOL(dump_fpu); | ||
| 329 | |||
| 330 | /* | ||
| 331 | * Shuffle the argument into the correct register before calling the | 313 | * Shuffle the argument into the correct register before calling the |
| 332 | * thread function. x1 is the thread argument, x2 is the pointer to | 314 | * thread function. x1 is the thread argument, x2 is the pointer to |
| 333 | * the thread function, and x3 points to the exit function. | 315 | * the thread function, and x3 points to the exit function. |
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 226b6bf6e9c2..538300f2273d 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c | |||
| @@ -211,8 +211,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) | |||
| 211 | * before we continue. | 211 | * before we continue. |
| 212 | */ | 212 | */ |
| 213 | set_cpu_online(cpu, true); | 213 | set_cpu_online(cpu, true); |
| 214 | while (!cpu_active(cpu)) | 214 | complete(&cpu_running); |
| 215 | cpu_relax(); | ||
| 216 | 215 | ||
| 217 | /* | 216 | /* |
| 218 | * OK, it's off to the idle thread for us | 217 | * OK, it's off to the idle thread for us |
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index efbf7df05d3f..4cd28931dba9 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c | |||
| @@ -80,7 +80,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) | |||
| 80 | #ifdef CONFIG_ZONE_DMA32 | 80 | #ifdef CONFIG_ZONE_DMA32 |
| 81 | /* 4GB maximum for 32-bit only capable devices */ | 81 | /* 4GB maximum for 32-bit only capable devices */ |
| 82 | max_dma32 = min(max, MAX_DMA32_PFN); | 82 | max_dma32 = min(max, MAX_DMA32_PFN); |
| 83 | zone_size[ZONE_DMA32] = max_dma32 - min; | 83 | zone_size[ZONE_DMA32] = max(min, max_dma32) - min; |
| 84 | #endif | 84 | #endif |
| 85 | zone_size[ZONE_NORMAL] = max - max_dma32; | 85 | zone_size[ZONE_NORMAL] = max - max_dma32; |
| 86 | 86 | ||
diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c index d38246e33ddb..9f883bf76953 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c +++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | * measurement, and debugging facilities. | 30 | * measurement, and debugging facilities. |
| 31 | */ | 31 | */ |
| 32 | 32 | ||
| 33 | #include <linux/irqflags.h> | ||
| 33 | #include <asm/octeon/cvmx.h> | 34 | #include <asm/octeon/cvmx.h> |
| 34 | #include <asm/octeon/cvmx-l2c.h> | 35 | #include <asm/octeon/cvmx-l2c.h> |
| 35 | #include <asm/octeon/cvmx-spinlock.h> | 36 | #include <asm/octeon/cvmx-spinlock.h> |
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 82ad35ce2b45..46ac73abd5ee 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #endif | 14 | #endif |
| 15 | 15 | ||
| 16 | #include <linux/compiler.h> | 16 | #include <linux/compiler.h> |
| 17 | #include <linux/irqflags.h> | ||
| 18 | #include <linux/types.h> | 17 | #include <linux/types.h> |
| 19 | #include <asm/barrier.h> | 18 | #include <asm/barrier.h> |
| 20 | #include <asm/byteorder.h> /* sigh ... */ | 19 | #include <asm/byteorder.h> /* sigh ... */ |
| @@ -44,6 +43,24 @@ | |||
| 44 | #define smp_mb__before_clear_bit() smp_mb__before_llsc() | 43 | #define smp_mb__before_clear_bit() smp_mb__before_llsc() |
| 45 | #define smp_mb__after_clear_bit() smp_llsc_mb() | 44 | #define smp_mb__after_clear_bit() smp_llsc_mb() |
| 46 | 45 | ||
| 46 | |||
| 47 | /* | ||
| 48 | * These are the "slower" versions of the functions and are in bitops.c. | ||
| 49 | * These functions call raw_local_irq_{save,restore}(). | ||
| 50 | */ | ||
| 51 | void __mips_set_bit(unsigned long nr, volatile unsigned long *addr); | ||
| 52 | void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr); | ||
| 53 | void __mips_change_bit(unsigned long nr, volatile unsigned long *addr); | ||
| 54 | int __mips_test_and_set_bit(unsigned long nr, | ||
| 55 | volatile unsigned long *addr); | ||
| 56 | int __mips_test_and_set_bit_lock(unsigned long nr, | ||
| 57 | volatile unsigned long *addr); | ||
| 58 | int __mips_test_and_clear_bit(unsigned long nr, | ||
| 59 | volatile unsigned long *addr); | ||
| 60 | int __mips_test_and_change_bit(unsigned long nr, | ||
| 61 | volatile unsigned long *addr); | ||
| 62 | |||
| 63 | |||
| 47 | /* | 64 | /* |
| 48 | * set_bit - Atomically set a bit in memory | 65 | * set_bit - Atomically set a bit in memory |
| 49 | * @nr: the bit to set | 66 | * @nr: the bit to set |
| @@ -57,7 +74,7 @@ | |||
| 57 | static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | 74 | static inline void set_bit(unsigned long nr, volatile unsigned long *addr) |
| 58 | { | 75 | { |
| 59 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 76 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
| 60 | unsigned short bit = nr & SZLONG_MASK; | 77 | int bit = nr & SZLONG_MASK; |
| 61 | unsigned long temp; | 78 | unsigned long temp; |
| 62 | 79 | ||
| 63 | if (kernel_uses_llsc && R10000_LLSC_WAR) { | 80 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| @@ -92,17 +109,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 92 | : "=&r" (temp), "+m" (*m) | 109 | : "=&r" (temp), "+m" (*m) |
| 93 | : "ir" (1UL << bit)); | 110 | : "ir" (1UL << bit)); |
| 94 | } while (unlikely(!temp)); | 111 | } while (unlikely(!temp)); |
| 95 | } else { | 112 | } else |
| 96 | volatile unsigned long *a = addr; | 113 | __mips_set_bit(nr, addr); |
| 97 | unsigned long mask; | ||
| 98 | unsigned long flags; | ||
| 99 | |||
| 100 | a += nr >> SZLONG_LOG; | ||
| 101 | mask = 1UL << bit; | ||
| 102 | raw_local_irq_save(flags); | ||
| 103 | *a |= mask; | ||
| 104 | raw_local_irq_restore(flags); | ||
| 105 | } | ||
| 106 | } | 114 | } |
| 107 | 115 | ||
| 108 | /* | 116 | /* |
| @@ -118,7 +126,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 118 | static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | 126 | static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) |
| 119 | { | 127 | { |
| 120 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 128 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
| 121 | unsigned short bit = nr & SZLONG_MASK; | 129 | int bit = nr & SZLONG_MASK; |
| 122 | unsigned long temp; | 130 | unsigned long temp; |
| 123 | 131 | ||
| 124 | if (kernel_uses_llsc && R10000_LLSC_WAR) { | 132 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| @@ -153,17 +161,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 153 | : "=&r" (temp), "+m" (*m) | 161 | : "=&r" (temp), "+m" (*m) |
| 154 | : "ir" (~(1UL << bit))); | 162 | : "ir" (~(1UL << bit))); |
| 155 | } while (unlikely(!temp)); | 163 | } while (unlikely(!temp)); |
| 156 | } else { | 164 | } else |
| 157 | volatile unsigned long *a = addr; | 165 | __mips_clear_bit(nr, addr); |
| 158 | unsigned long mask; | ||
| 159 | unsigned long flags; | ||
| 160 | |||
| 161 | a += nr >> SZLONG_LOG; | ||
| 162 | mask = 1UL << bit; | ||
| 163 | raw_local_irq_save(flags); | ||
| 164 | *a &= ~mask; | ||
| 165 | raw_local_irq_restore(flags); | ||
| 166 | } | ||
| 167 | } | 166 | } |
| 168 | 167 | ||
| 169 | /* | 168 | /* |
| @@ -191,7 +190,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad | |||
| 191 | */ | 190 | */ |
| 192 | static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | 191 | static inline void change_bit(unsigned long nr, volatile unsigned long *addr) |
| 193 | { | 192 | { |
| 194 | unsigned short bit = nr & SZLONG_MASK; | 193 | int bit = nr & SZLONG_MASK; |
| 195 | 194 | ||
| 196 | if (kernel_uses_llsc && R10000_LLSC_WAR) { | 195 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| 197 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 196 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
| @@ -220,17 +219,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 220 | : "=&r" (temp), "+m" (*m) | 219 | : "=&r" (temp), "+m" (*m) |
| 221 | : "ir" (1UL << bit)); | 220 | : "ir" (1UL << bit)); |
| 222 | } while (unlikely(!temp)); | 221 | } while (unlikely(!temp)); |
| 223 | } else { | 222 | } else |
| 224 | volatile unsigned long *a = addr; | 223 | __mips_change_bit(nr, addr); |
| 225 | unsigned long mask; | ||
| 226 | unsigned long flags; | ||
| 227 | |||
| 228 | a += nr >> SZLONG_LOG; | ||
| 229 | mask = 1UL << bit; | ||
| 230 | raw_local_irq_save(flags); | ||
| 231 | *a ^= mask; | ||
| 232 | raw_local_irq_restore(flags); | ||
| 233 | } | ||
| 234 | } | 224 | } |
| 235 | 225 | ||
| 236 | /* | 226 | /* |
| @@ -244,7 +234,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 244 | static inline int test_and_set_bit(unsigned long nr, | 234 | static inline int test_and_set_bit(unsigned long nr, |
| 245 | volatile unsigned long *addr) | 235 | volatile unsigned long *addr) |
| 246 | { | 236 | { |
| 247 | unsigned short bit = nr & SZLONG_MASK; | 237 | int bit = nr & SZLONG_MASK; |
| 248 | unsigned long res; | 238 | unsigned long res; |
| 249 | 239 | ||
| 250 | smp_mb__before_llsc(); | 240 | smp_mb__before_llsc(); |
| @@ -281,18 +271,8 @@ static inline int test_and_set_bit(unsigned long nr, | |||
| 281 | } while (unlikely(!res)); | 271 | } while (unlikely(!res)); |
| 282 | 272 | ||
| 283 | res = temp & (1UL << bit); | 273 | res = temp & (1UL << bit); |
| 284 | } else { | 274 | } else |
| 285 | volatile unsigned long *a = addr; | 275 | res = __mips_test_and_set_bit(nr, addr); |
| 286 | unsigned long mask; | ||
| 287 | unsigned long flags; | ||
| 288 | |||
| 289 | a += nr >> SZLONG_LOG; | ||
| 290 | mask = 1UL << bit; | ||
| 291 | raw_local_irq_save(flags); | ||
| 292 | res = (mask & *a); | ||
| 293 | *a |= mask; | ||
| 294 | raw_local_irq_restore(flags); | ||
| 295 | } | ||
| 296 | 276 | ||
| 297 | smp_llsc_mb(); | 277 | smp_llsc_mb(); |
| 298 | 278 | ||
| @@ -310,7 +290,7 @@ static inline int test_and_set_bit(unsigned long nr, | |||
| 310 | static inline int test_and_set_bit_lock(unsigned long nr, | 290 | static inline int test_and_set_bit_lock(unsigned long nr, |
| 311 | volatile unsigned long *addr) | 291 | volatile unsigned long *addr) |
| 312 | { | 292 | { |
| 313 | unsigned short bit = nr & SZLONG_MASK; | 293 | int bit = nr & SZLONG_MASK; |
| 314 | unsigned long res; | 294 | unsigned long res; |
| 315 | 295 | ||
| 316 | if (kernel_uses_llsc && R10000_LLSC_WAR) { | 296 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| @@ -345,18 +325,8 @@ static inline int test_and_set_bit_lock(unsigned long nr, | |||
| 345 | } while (unlikely(!res)); | 325 | } while (unlikely(!res)); |
| 346 | 326 | ||
| 347 | res = temp & (1UL << bit); | 327 | res = temp & (1UL << bit); |
| 348 | } else { | 328 | } else |
| 349 | volatile unsigned long *a = addr; | 329 | res = __mips_test_and_set_bit_lock(nr, addr); |
| 350 | unsigned long mask; | ||
| 351 | unsigned long flags; | ||
| 352 | |||
| 353 | a += nr >> SZLONG_LOG; | ||
| 354 | mask = 1UL << bit; | ||
| 355 | raw_local_irq_save(flags); | ||
| 356 | res = (mask & *a); | ||
| 357 | *a |= mask; | ||
| 358 | raw_local_irq_restore(flags); | ||
| 359 | } | ||
| 360 | 330 | ||
| 361 | smp_llsc_mb(); | 331 | smp_llsc_mb(); |
| 362 | 332 | ||
| @@ -373,7 +343,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, | |||
| 373 | static inline int test_and_clear_bit(unsigned long nr, | 343 | static inline int test_and_clear_bit(unsigned long nr, |
| 374 | volatile unsigned long *addr) | 344 | volatile unsigned long *addr) |
| 375 | { | 345 | { |
| 376 | unsigned short bit = nr & SZLONG_MASK; | 346 | int bit = nr & SZLONG_MASK; |
| 377 | unsigned long res; | 347 | unsigned long res; |
| 378 | 348 | ||
| 379 | smp_mb__before_llsc(); | 349 | smp_mb__before_llsc(); |
| @@ -428,18 +398,8 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
| 428 | } while (unlikely(!res)); | 398 | } while (unlikely(!res)); |
| 429 | 399 | ||
| 430 | res = temp & (1UL << bit); | 400 | res = temp & (1UL << bit); |
| 431 | } else { | 401 | } else |
| 432 | volatile unsigned long *a = addr; | 402 | res = __mips_test_and_clear_bit(nr, addr); |
| 433 | unsigned long mask; | ||
| 434 | unsigned long flags; | ||
| 435 | |||
| 436 | a += nr >> SZLONG_LOG; | ||
| 437 | mask = 1UL << bit; | ||
| 438 | raw_local_irq_save(flags); | ||
| 439 | res = (mask & *a); | ||
| 440 | *a &= ~mask; | ||
| 441 | raw_local_irq_restore(flags); | ||
| 442 | } | ||
| 443 | 403 | ||
| 444 | smp_llsc_mb(); | 404 | smp_llsc_mb(); |
| 445 | 405 | ||
| @@ -457,7 +417,7 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
| 457 | static inline int test_and_change_bit(unsigned long nr, | 417 | static inline int test_and_change_bit(unsigned long nr, |
| 458 | volatile unsigned long *addr) | 418 | volatile unsigned long *addr) |
| 459 | { | 419 | { |
| 460 | unsigned short bit = nr & SZLONG_MASK; | 420 | int bit = nr & SZLONG_MASK; |
| 461 | unsigned long res; | 421 | unsigned long res; |
| 462 | 422 | ||
| 463 | smp_mb__before_llsc(); | 423 | smp_mb__before_llsc(); |
| @@ -494,18 +454,8 @@ static inline int test_and_change_bit(unsigned long nr, | |||
| 494 | } while (unlikely(!res)); | 454 | } while (unlikely(!res)); |
| 495 | 455 | ||
| 496 | res = temp & (1UL << bit); | 456 | res = temp & (1UL << bit); |
| 497 | } else { | 457 | } else |
| 498 | volatile unsigned long *a = addr; | 458 | res = __mips_test_and_change_bit(nr, addr); |
| 499 | unsigned long mask; | ||
| 500 | unsigned long flags; | ||
| 501 | |||
| 502 | a += nr >> SZLONG_LOG; | ||
| 503 | mask = 1UL << bit; | ||
| 504 | raw_local_irq_save(flags); | ||
| 505 | res = (mask & *a); | ||
| 506 | *a ^= mask; | ||
| 507 | raw_local_irq_restore(flags); | ||
| 508 | } | ||
| 509 | 459 | ||
| 510 | smp_llsc_mb(); | 460 | smp_llsc_mb(); |
| 511 | 461 | ||
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index 58277e0e9cd4..3c5d1464b7bd 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h | |||
| @@ -290,7 +290,7 @@ struct compat_shmid64_ds { | |||
| 290 | 290 | ||
| 291 | static inline int is_compat_task(void) | 291 | static inline int is_compat_task(void) |
| 292 | { | 292 | { |
| 293 | return test_thread_flag(TIF_32BIT); | 293 | return test_thread_flag(TIF_32BIT_ADDR); |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | #endif /* _ASM_COMPAT_H */ | 296 | #endif /* _ASM_COMPAT_H */ |
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 29d9c23c20c7..ff2e0345e013 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/compiler.h> | 15 | #include <linux/compiler.h> |
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
| 18 | #include <linux/irqflags.h> | ||
| 18 | 19 | ||
| 19 | #include <asm/addrspace.h> | 20 | #include <asm/addrspace.h> |
| 20 | #include <asm/bug.h> | 21 | #include <asm/bug.h> |
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index 309cbcd6909c..9f3384c789d7 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h | |||
| @@ -16,83 +16,13 @@ | |||
| 16 | #include <linux/compiler.h> | 16 | #include <linux/compiler.h> |
| 17 | #include <asm/hazards.h> | 17 | #include <asm/hazards.h> |
| 18 | 18 | ||
| 19 | __asm__( | 19 | #if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) |
| 20 | " .macro arch_local_irq_enable \n" | ||
| 21 | " .set push \n" | ||
| 22 | " .set reorder \n" | ||
| 23 | " .set noat \n" | ||
| 24 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 25 | " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" | ||
| 26 | " ori $1, 0x400 \n" | ||
| 27 | " xori $1, 0x400 \n" | ||
| 28 | " mtc0 $1, $2, 1 \n" | ||
| 29 | #elif defined(CONFIG_CPU_MIPSR2) | ||
| 30 | " ei \n" | ||
| 31 | #else | ||
| 32 | " mfc0 $1,$12 \n" | ||
| 33 | " ori $1,0x1f \n" | ||
| 34 | " xori $1,0x1e \n" | ||
| 35 | " mtc0 $1,$12 \n" | ||
| 36 | #endif | ||
| 37 | " irq_enable_hazard \n" | ||
| 38 | " .set pop \n" | ||
| 39 | " .endm"); | ||
| 40 | 20 | ||
| 41 | extern void smtc_ipi_replay(void); | ||
| 42 | |||
| 43 | static inline void arch_local_irq_enable(void) | ||
| 44 | { | ||
| 45 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 46 | /* | ||
| 47 | * SMTC kernel needs to do a software replay of queued | ||
| 48 | * IPIs, at the cost of call overhead on each local_irq_enable() | ||
| 49 | */ | ||
| 50 | smtc_ipi_replay(); | ||
| 51 | #endif | ||
| 52 | __asm__ __volatile__( | ||
| 53 | "arch_local_irq_enable" | ||
| 54 | : /* no outputs */ | ||
| 55 | : /* no inputs */ | ||
| 56 | : "memory"); | ||
| 57 | } | ||
| 58 | |||
| 59 | |||
| 60 | /* | ||
| 61 | * For cli() we have to insert nops to make sure that the new value | ||
| 62 | * has actually arrived in the status register before the end of this | ||
| 63 | * macro. | ||
| 64 | * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | ||
| 65 | * no nops at all. | ||
| 66 | */ | ||
| 67 | /* | ||
| 68 | * For TX49, operating only IE bit is not enough. | ||
| 69 | * | ||
| 70 | * If mfc0 $12 follows store and the mfc0 is last instruction of a | ||
| 71 | * page and fetching the next instruction causes TLB miss, the result | ||
| 72 | * of the mfc0 might wrongly contain EXL bit. | ||
| 73 | * | ||
| 74 | * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 | ||
| 75 | * | ||
| 76 | * Workaround: mask EXL bit of the result or place a nop before mfc0. | ||
| 77 | */ | ||
| 78 | __asm__( | 21 | __asm__( |
| 79 | " .macro arch_local_irq_disable\n" | 22 | " .macro arch_local_irq_disable\n" |
| 80 | " .set push \n" | 23 | " .set push \n" |
| 81 | " .set noat \n" | 24 | " .set noat \n" |
| 82 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 83 | " mfc0 $1, $2, 1 \n" | ||
| 84 | " ori $1, 0x400 \n" | ||
| 85 | " .set noreorder \n" | ||
| 86 | " mtc0 $1, $2, 1 \n" | ||
| 87 | #elif defined(CONFIG_CPU_MIPSR2) | ||
| 88 | " di \n" | 25 | " di \n" |
| 89 | #else | ||
| 90 | " mfc0 $1,$12 \n" | ||
| 91 | " ori $1,0x1f \n" | ||
| 92 | " xori $1,0x1f \n" | ||
| 93 | " .set noreorder \n" | ||
| 94 | " mtc0 $1,$12 \n" | ||
| 95 | #endif | ||
| 96 | " irq_disable_hazard \n" | 26 | " irq_disable_hazard \n" |
| 97 | " .set pop \n" | 27 | " .set pop \n" |
| 98 | " .endm \n"); | 28 | " .endm \n"); |
| @@ -106,46 +36,14 @@ static inline void arch_local_irq_disable(void) | |||
| 106 | : "memory"); | 36 | : "memory"); |
| 107 | } | 37 | } |
| 108 | 38 | ||
| 109 | __asm__( | ||
| 110 | " .macro arch_local_save_flags flags \n" | ||
| 111 | " .set push \n" | ||
| 112 | " .set reorder \n" | ||
| 113 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 114 | " mfc0 \\flags, $2, 1 \n" | ||
| 115 | #else | ||
| 116 | " mfc0 \\flags, $12 \n" | ||
| 117 | #endif | ||
| 118 | " .set pop \n" | ||
| 119 | " .endm \n"); | ||
| 120 | |||
| 121 | static inline unsigned long arch_local_save_flags(void) | ||
| 122 | { | ||
| 123 | unsigned long flags; | ||
| 124 | asm volatile("arch_local_save_flags %0" : "=r" (flags)); | ||
| 125 | return flags; | ||
| 126 | } | ||
| 127 | 39 | ||
| 128 | __asm__( | 40 | __asm__( |
| 129 | " .macro arch_local_irq_save result \n" | 41 | " .macro arch_local_irq_save result \n" |
| 130 | " .set push \n" | 42 | " .set push \n" |
| 131 | " .set reorder \n" | 43 | " .set reorder \n" |
| 132 | " .set noat \n" | 44 | " .set noat \n" |
| 133 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 134 | " mfc0 \\result, $2, 1 \n" | ||
| 135 | " ori $1, \\result, 0x400 \n" | ||
| 136 | " .set noreorder \n" | ||
| 137 | " mtc0 $1, $2, 1 \n" | ||
| 138 | " andi \\result, \\result, 0x400 \n" | ||
| 139 | #elif defined(CONFIG_CPU_MIPSR2) | ||
| 140 | " di \\result \n" | 45 | " di \\result \n" |
| 141 | " andi \\result, 1 \n" | 46 | " andi \\result, 1 \n" |
| 142 | #else | ||
| 143 | " mfc0 \\result, $12 \n" | ||
| 144 | " ori $1, \\result, 0x1f \n" | ||
| 145 | " xori $1, 0x1f \n" | ||
| 146 | " .set noreorder \n" | ||
| 147 | " mtc0 $1, $12 \n" | ||
| 148 | #endif | ||
| 149 | " irq_disable_hazard \n" | 47 | " irq_disable_hazard \n" |
| 150 | " .set pop \n" | 48 | " .set pop \n" |
| 151 | " .endm \n"); | 49 | " .endm \n"); |
| @@ -160,61 +58,37 @@ static inline unsigned long arch_local_irq_save(void) | |||
| 160 | return flags; | 58 | return flags; |
| 161 | } | 59 | } |
| 162 | 60 | ||
| 61 | |||
| 163 | __asm__( | 62 | __asm__( |
| 164 | " .macro arch_local_irq_restore flags \n" | 63 | " .macro arch_local_irq_restore flags \n" |
| 165 | " .set push \n" | 64 | " .set push \n" |
| 166 | " .set noreorder \n" | 65 | " .set noreorder \n" |
| 167 | " .set noat \n" | 66 | " .set noat \n" |
| 168 | #ifdef CONFIG_MIPS_MT_SMTC | 67 | #if defined(CONFIG_IRQ_CPU) |
| 169 | "mfc0 $1, $2, 1 \n" | ||
| 170 | "andi \\flags, 0x400 \n" | ||
| 171 | "ori $1, 0x400 \n" | ||
| 172 | "xori $1, 0x400 \n" | ||
| 173 | "or \\flags, $1 \n" | ||
| 174 | "mtc0 \\flags, $2, 1 \n" | ||
| 175 | #elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | ||
| 176 | /* | 68 | /* |
| 177 | * Slow, but doesn't suffer from a relatively unlikely race | 69 | * Slow, but doesn't suffer from a relatively unlikely race |
| 178 | * condition we're having since days 1. | 70 | * condition we're having since days 1. |
| 179 | */ | 71 | */ |
| 180 | " beqz \\flags, 1f \n" | 72 | " beqz \\flags, 1f \n" |
| 181 | " di \n" | 73 | " di \n" |
| 182 | " ei \n" | 74 | " ei \n" |
| 183 | "1: \n" | 75 | "1: \n" |
| 184 | #elif defined(CONFIG_CPU_MIPSR2) | 76 | #else |
| 185 | /* | 77 | /* |
| 186 | * Fast, dangerous. Life is fun, life is good. | 78 | * Fast, dangerous. Life is fun, life is good. |
| 187 | */ | 79 | */ |
| 188 | " mfc0 $1, $12 \n" | 80 | " mfc0 $1, $12 \n" |
| 189 | " ins $1, \\flags, 0, 1 \n" | 81 | " ins $1, \\flags, 0, 1 \n" |
| 190 | " mtc0 $1, $12 \n" | 82 | " mtc0 $1, $12 \n" |
| 191 | #else | ||
| 192 | " mfc0 $1, $12 \n" | ||
| 193 | " andi \\flags, 1 \n" | ||
| 194 | " ori $1, 0x1f \n" | ||
| 195 | " xori $1, 0x1f \n" | ||
| 196 | " or \\flags, $1 \n" | ||
| 197 | " mtc0 \\flags, $12 \n" | ||
| 198 | #endif | 83 | #endif |
| 199 | " irq_disable_hazard \n" | 84 | " irq_disable_hazard \n" |
| 200 | " .set pop \n" | 85 | " .set pop \n" |
| 201 | " .endm \n"); | 86 | " .endm \n"); |
| 202 | 87 | ||
| 203 | |||
| 204 | static inline void arch_local_irq_restore(unsigned long flags) | 88 | static inline void arch_local_irq_restore(unsigned long flags) |
| 205 | { | 89 | { |
| 206 | unsigned long __tmp1; | 90 | unsigned long __tmp1; |
| 207 | 91 | ||
| 208 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 209 | /* | ||
| 210 | * SMTC kernel needs to do a software replay of queued | ||
| 211 | * IPIs, at the cost of branch and call overhead on each | ||
| 212 | * local_irq_restore() | ||
| 213 | */ | ||
| 214 | if (unlikely(!(flags & 0x0400))) | ||
| 215 | smtc_ipi_replay(); | ||
| 216 | #endif | ||
| 217 | |||
| 218 | __asm__ __volatile__( | 92 | __asm__ __volatile__( |
| 219 | "arch_local_irq_restore\t%0" | 93 | "arch_local_irq_restore\t%0" |
| 220 | : "=r" (__tmp1) | 94 | : "=r" (__tmp1) |
| @@ -232,6 +106,75 @@ static inline void __arch_local_irq_restore(unsigned long flags) | |||
| 232 | : "0" (flags) | 106 | : "0" (flags) |
| 233 | : "memory"); | 107 | : "memory"); |
| 234 | } | 108 | } |
| 109 | #else | ||
| 110 | /* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ | ||
| 111 | void arch_local_irq_disable(void); | ||
| 112 | unsigned long arch_local_irq_save(void); | ||
| 113 | void arch_local_irq_restore(unsigned long flags); | ||
| 114 | void __arch_local_irq_restore(unsigned long flags); | ||
| 115 | #endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */ | ||
| 116 | |||
| 117 | |||
| 118 | __asm__( | ||
| 119 | " .macro arch_local_irq_enable \n" | ||
| 120 | " .set push \n" | ||
| 121 | " .set reorder \n" | ||
| 122 | " .set noat \n" | ||
| 123 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 124 | " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" | ||
| 125 | " ori $1, 0x400 \n" | ||
| 126 | " xori $1, 0x400 \n" | ||
| 127 | " mtc0 $1, $2, 1 \n" | ||
| 128 | #elif defined(CONFIG_CPU_MIPSR2) | ||
| 129 | " ei \n" | ||
| 130 | #else | ||
| 131 | " mfc0 $1,$12 \n" | ||
| 132 | " ori $1,0x1f \n" | ||
| 133 | " xori $1,0x1e \n" | ||
| 134 | " mtc0 $1,$12 \n" | ||
| 135 | #endif | ||
| 136 | " irq_enable_hazard \n" | ||
| 137 | " .set pop \n" | ||
| 138 | " .endm"); | ||
| 139 | |||
| 140 | extern void smtc_ipi_replay(void); | ||
| 141 | |||
| 142 | static inline void arch_local_irq_enable(void) | ||
| 143 | { | ||
| 144 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 145 | /* | ||
| 146 | * SMTC kernel needs to do a software replay of queued | ||
| 147 | * IPIs, at the cost of call overhead on each local_irq_enable() | ||
| 148 | */ | ||
| 149 | smtc_ipi_replay(); | ||
| 150 | #endif | ||
| 151 | __asm__ __volatile__( | ||
| 152 | "arch_local_irq_enable" | ||
| 153 | : /* no outputs */ | ||
| 154 | : /* no inputs */ | ||
| 155 | : "memory"); | ||
| 156 | } | ||
| 157 | |||
| 158 | |||
| 159 | __asm__( | ||
| 160 | " .macro arch_local_save_flags flags \n" | ||
| 161 | " .set push \n" | ||
| 162 | " .set reorder \n" | ||
| 163 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 164 | " mfc0 \\flags, $2, 1 \n" | ||
| 165 | #else | ||
| 166 | " mfc0 \\flags, $12 \n" | ||
| 167 | #endif | ||
| 168 | " .set pop \n" | ||
| 169 | " .endm \n"); | ||
| 170 | |||
| 171 | static inline unsigned long arch_local_save_flags(void) | ||
| 172 | { | ||
| 173 | unsigned long flags; | ||
| 174 | asm volatile("arch_local_save_flags %0" : "=r" (flags)); | ||
| 175 | return flags; | ||
| 176 | } | ||
| 177 | |||
| 235 | 178 | ||
| 236 | static inline int arch_irqs_disabled_flags(unsigned long flags) | 179 | static inline int arch_irqs_disabled_flags(unsigned long flags) |
| 237 | { | 180 | { |
| @@ -245,7 +188,7 @@ static inline int arch_irqs_disabled_flags(unsigned long flags) | |||
| 245 | #endif | 188 | #endif |
| 246 | } | 189 | } |
| 247 | 190 | ||
| 248 | #endif | 191 | #endif /* #ifndef __ASSEMBLY__ */ |
| 249 | 192 | ||
| 250 | /* | 193 | /* |
| 251 | * Do the CPU's IRQ-state tracing from assembly code. | 194 | * Do the CPU's IRQ-state tracing from assembly code. |
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 8debe9e91754..18806a52061c 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
| @@ -112,12 +112,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
| 112 | #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ | 112 | #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ |
| 113 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ | 113 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ |
| 114 | 114 | ||
| 115 | #ifdef CONFIG_MIPS32_O32 | ||
| 116 | #define TIF_32BIT TIF_32BIT_REGS | ||
| 117 | #elif defined(CONFIG_MIPS32_N32) | ||
| 118 | #define TIF_32BIT _TIF_32BIT_ADDR | ||
| 119 | #endif /* CONFIG_MIPS32_O32 */ | ||
| 120 | |||
| 121 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 115 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
| 122 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | 116 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) |
| 123 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 117 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index c4a82e841c73..eeddc58802e1 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile | |||
| @@ -2,8 +2,9 @@ | |||
| 2 | # Makefile for MIPS-specific library files.. | 2 | # Makefile for MIPS-specific library files.. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | lib-y += csum_partial.o delay.o memcpy.o memset.o \ | 5 | lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ |
| 6 | strlen_user.o strncpy_user.o strnlen_user.o uncached.o | 6 | mips-atomic.o strlen_user.o strncpy_user.o \ |
| 7 | strnlen_user.o uncached.o | ||
| 7 | 8 | ||
| 8 | obj-y += iomap.o | 9 | obj-y += iomap.o |
| 9 | obj-$(CONFIG_PCI) += iomap-pci.o | 10 | obj-$(CONFIG_PCI) += iomap-pci.o |
diff --git a/arch/mips/lib/bitops.c b/arch/mips/lib/bitops.c new file mode 100644 index 000000000000..239a9c957b02 --- /dev/null +++ b/arch/mips/lib/bitops.c | |||
| @@ -0,0 +1,179 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org) | ||
| 7 | * Copyright (c) 1999, 2000 Silicon Graphics, Inc. | ||
| 8 | */ | ||
| 9 | #include <linux/bitops.h> | ||
| 10 | #include <linux/irqflags.h> | ||
| 11 | #include <linux/export.h> | ||
| 12 | |||
| 13 | |||
| 14 | /** | ||
| 15 | * __mips_set_bit - Atomically set a bit in memory. This is called by | ||
| 16 | * set_bit() if it cannot find a faster solution. | ||
| 17 | * @nr: the bit to set | ||
| 18 | * @addr: the address to start counting from | ||
| 19 | */ | ||
| 20 | void __mips_set_bit(unsigned long nr, volatile unsigned long *addr) | ||
| 21 | { | ||
| 22 | volatile unsigned long *a = addr; | ||
| 23 | unsigned bit = nr & SZLONG_MASK; | ||
| 24 | unsigned long mask; | ||
| 25 | unsigned long flags; | ||
| 26 | |||
| 27 | a += nr >> SZLONG_LOG; | ||
| 28 | mask = 1UL << bit; | ||
| 29 | raw_local_irq_save(flags); | ||
| 30 | *a |= mask; | ||
| 31 | raw_local_irq_restore(flags); | ||
| 32 | } | ||
| 33 | EXPORT_SYMBOL(__mips_set_bit); | ||
| 34 | |||
| 35 | |||
| 36 | /** | ||
| 37 | * __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if | ||
| 38 | * it cannot find a faster solution. | ||
| 39 | * @nr: Bit to clear | ||
| 40 | * @addr: Address to start counting from | ||
| 41 | */ | ||
| 42 | void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr) | ||
| 43 | { | ||
| 44 | volatile unsigned long *a = addr; | ||
| 45 | unsigned bit = nr & SZLONG_MASK; | ||
| 46 | unsigned long mask; | ||
| 47 | unsigned long flags; | ||
| 48 | |||
| 49 | a += nr >> SZLONG_LOG; | ||
| 50 | mask = 1UL << bit; | ||
| 51 | raw_local_irq_save(flags); | ||
| 52 | *a &= ~mask; | ||
| 53 | raw_local_irq_restore(flags); | ||
| 54 | } | ||
| 55 | EXPORT_SYMBOL(__mips_clear_bit); | ||
| 56 | |||
| 57 | |||
| 58 | /** | ||
| 59 | * __mips_change_bit - Toggle a bit in memory. This is called by change_bit() | ||
| 60 | * if it cannot find a faster solution. | ||
| 61 | * @nr: Bit to change | ||
| 62 | * @addr: Address to start counting from | ||
| 63 | */ | ||
| 64 | void __mips_change_bit(unsigned long nr, volatile unsigned long *addr) | ||
| 65 | { | ||
| 66 | volatile unsigned long *a = addr; | ||
| 67 | unsigned bit = nr & SZLONG_MASK; | ||
| 68 | unsigned long mask; | ||
| 69 | unsigned long flags; | ||
| 70 | |||
| 71 | a += nr >> SZLONG_LOG; | ||
| 72 | mask = 1UL << bit; | ||
| 73 | raw_local_irq_save(flags); | ||
| 74 | *a ^= mask; | ||
| 75 | raw_local_irq_restore(flags); | ||
| 76 | } | ||
| 77 | EXPORT_SYMBOL(__mips_change_bit); | ||
| 78 | |||
| 79 | |||
| 80 | /** | ||
| 81 | * __mips_test_and_set_bit - Set a bit and return its old value. This is | ||
| 82 | * called by test_and_set_bit() if it cannot find a faster solution. | ||
| 83 | * @nr: Bit to set | ||
| 84 | * @addr: Address to count from | ||
| 85 | */ | ||
| 86 | int __mips_test_and_set_bit(unsigned long nr, | ||
| 87 | volatile unsigned long *addr) | ||
| 88 | { | ||
| 89 | volatile unsigned long *a = addr; | ||
| 90 | unsigned bit = nr & SZLONG_MASK; | ||
| 91 | unsigned long mask; | ||
| 92 | unsigned long flags; | ||
| 93 | unsigned long res; | ||
| 94 | |||
| 95 | a += nr >> SZLONG_LOG; | ||
| 96 | mask = 1UL << bit; | ||
| 97 | raw_local_irq_save(flags); | ||
| 98 | res = (mask & *a); | ||
| 99 | *a |= mask; | ||
| 100 | raw_local_irq_restore(flags); | ||
| 101 | return res; | ||
| 102 | } | ||
| 103 | EXPORT_SYMBOL(__mips_test_and_set_bit); | ||
| 104 | |||
| 105 | |||
| 106 | /** | ||
| 107 | * __mips_test_and_set_bit_lock - Set a bit and return its old value. This is | ||
| 108 | * called by test_and_set_bit_lock() if it cannot find a faster solution. | ||
| 109 | * @nr: Bit to set | ||
| 110 | * @addr: Address to count from | ||
| 111 | */ | ||
| 112 | int __mips_test_and_set_bit_lock(unsigned long nr, | ||
| 113 | volatile unsigned long *addr) | ||
| 114 | { | ||
| 115 | volatile unsigned long *a = addr; | ||
| 116 | unsigned bit = nr & SZLONG_MASK; | ||
| 117 | unsigned long mask; | ||
| 118 | unsigned long flags; | ||
| 119 | unsigned long res; | ||
| 120 | |||
| 121 | a += nr >> SZLONG_LOG; | ||
| 122 | mask = 1UL << bit; | ||
| 123 | raw_local_irq_save(flags); | ||
| 124 | res = (mask & *a); | ||
| 125 | *a |= mask; | ||
| 126 | raw_local_irq_restore(flags); | ||
| 127 | return res; | ||
| 128 | } | ||
| 129 | EXPORT_SYMBOL(__mips_test_and_set_bit_lock); | ||
| 130 | |||
| 131 | |||
| 132 | /** | ||
| 133 | * __mips_test_and_clear_bit - Clear a bit and return its old value. This is | ||
| 134 | * called by test_and_clear_bit() if it cannot find a faster solution. | ||
| 135 | * @nr: Bit to clear | ||
| 136 | * @addr: Address to count from | ||
| 137 | */ | ||
| 138 | int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) | ||
| 139 | { | ||
| 140 | volatile unsigned long *a = addr; | ||
| 141 | unsigned bit = nr & SZLONG_MASK; | ||
| 142 | unsigned long mask; | ||
| 143 | unsigned long flags; | ||
| 144 | unsigned long res; | ||
| 145 | |||
| 146 | a += nr >> SZLONG_LOG; | ||
| 147 | mask = 1UL << bit; | ||
| 148 | raw_local_irq_save(flags); | ||
| 149 | res = (mask & *a); | ||
| 150 | *a &= ~mask; | ||
| 151 | raw_local_irq_restore(flags); | ||
| 152 | return res; | ||
| 153 | } | ||
| 154 | EXPORT_SYMBOL(__mips_test_and_clear_bit); | ||
| 155 | |||
| 156 | |||
| 157 | /** | ||
| 158 | * __mips_test_and_change_bit - Change a bit and return its old value. This is | ||
| 159 | * called by test_and_change_bit() if it cannot find a faster solution. | ||
| 160 | * @nr: Bit to change | ||
| 161 | * @addr: Address to count from | ||
| 162 | */ | ||
| 163 | int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr) | ||
| 164 | { | ||
| 165 | volatile unsigned long *a = addr; | ||
| 166 | unsigned bit = nr & SZLONG_MASK; | ||
| 167 | unsigned long mask; | ||
| 168 | unsigned long flags; | ||
| 169 | unsigned long res; | ||
| 170 | |||
| 171 | a += nr >> SZLONG_LOG; | ||
| 172 | mask = 1UL << bit; | ||
| 173 | raw_local_irq_save(flags); | ||
| 174 | res = (mask & *a); | ||
| 175 | *a ^= mask; | ||
| 176 | raw_local_irq_restore(flags); | ||
| 177 | return res; | ||
| 178 | } | ||
| 179 | EXPORT_SYMBOL(__mips_test_and_change_bit); | ||
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c new file mode 100644 index 000000000000..e091430dbeb1 --- /dev/null +++ b/arch/mips/lib/mips-atomic.c | |||
| @@ -0,0 +1,176 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle | ||
| 7 | * Copyright (C) 1996 by Paul M. Antoine | ||
| 8 | * Copyright (C) 1999 Silicon Graphics | ||
| 9 | * Copyright (C) 2000 MIPS Technologies, Inc. | ||
| 10 | */ | ||
| 11 | #include <asm/irqflags.h> | ||
| 12 | #include <asm/hazards.h> | ||
| 13 | #include <linux/compiler.h> | ||
| 14 | #include <linux/preempt.h> | ||
| 15 | #include <linux/export.h> | ||
| 16 | |||
| 17 | #if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) | ||
| 18 | |||
| 19 | /* | ||
| 20 | * For cli() we have to insert nops to make sure that the new value | ||
| 21 | * has actually arrived in the status register before the end of this | ||
| 22 | * macro. | ||
| 23 | * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | ||
| 24 | * no nops at all. | ||
| 25 | */ | ||
| 26 | /* | ||
| 27 | * For TX49, operating only IE bit is not enough. | ||
| 28 | * | ||
| 29 | * If mfc0 $12 follows store and the mfc0 is last instruction of a | ||
| 30 | * page and fetching the next instruction causes TLB miss, the result | ||
| 31 | * of the mfc0 might wrongly contain EXL bit. | ||
| 32 | * | ||
| 33 | * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 | ||
| 34 | * | ||
| 35 | * Workaround: mask EXL bit of the result or place a nop before mfc0. | ||
| 36 | */ | ||
| 37 | __asm__( | ||
| 38 | " .macro arch_local_irq_disable\n" | ||
| 39 | " .set push \n" | ||
| 40 | " .set noat \n" | ||
| 41 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 42 | " mfc0 $1, $2, 1 \n" | ||
| 43 | " ori $1, 0x400 \n" | ||
| 44 | " .set noreorder \n" | ||
| 45 | " mtc0 $1, $2, 1 \n" | ||
| 46 | #elif defined(CONFIG_CPU_MIPSR2) | ||
| 47 | /* see irqflags.h for inline function */ | ||
| 48 | #else | ||
| 49 | " mfc0 $1,$12 \n" | ||
| 50 | " ori $1,0x1f \n" | ||
| 51 | " xori $1,0x1f \n" | ||
| 52 | " .set noreorder \n" | ||
| 53 | " mtc0 $1,$12 \n" | ||
| 54 | #endif | ||
| 55 | " irq_disable_hazard \n" | ||
| 56 | " .set pop \n" | ||
| 57 | " .endm \n"); | ||
| 58 | |||
| 59 | void arch_local_irq_disable(void) | ||
| 60 | { | ||
| 61 | preempt_disable(); | ||
| 62 | __asm__ __volatile__( | ||
| 63 | "arch_local_irq_disable" | ||
| 64 | : /* no outputs */ | ||
| 65 | : /* no inputs */ | ||
| 66 | : "memory"); | ||
| 67 | preempt_enable(); | ||
| 68 | } | ||
| 69 | EXPORT_SYMBOL(arch_local_irq_disable); | ||
| 70 | |||
| 71 | |||
| 72 | __asm__( | ||
| 73 | " .macro arch_local_irq_save result \n" | ||
| 74 | " .set push \n" | ||
| 75 | " .set reorder \n" | ||
| 76 | " .set noat \n" | ||
| 77 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 78 | " mfc0 \\result, $2, 1 \n" | ||
| 79 | " ori $1, \\result, 0x400 \n" | ||
| 80 | " .set noreorder \n" | ||
| 81 | " mtc0 $1, $2, 1 \n" | ||
| 82 | " andi \\result, \\result, 0x400 \n" | ||
| 83 | #elif defined(CONFIG_CPU_MIPSR2) | ||
| 84 | /* see irqflags.h for inline function */ | ||
| 85 | #else | ||
| 86 | " mfc0 \\result, $12 \n" | ||
| 87 | " ori $1, \\result, 0x1f \n" | ||
| 88 | " xori $1, 0x1f \n" | ||
| 89 | " .set noreorder \n" | ||
| 90 | " mtc0 $1, $12 \n" | ||
| 91 | #endif | ||
| 92 | " irq_disable_hazard \n" | ||
| 93 | " .set pop \n" | ||
| 94 | " .endm \n"); | ||
| 95 | |||
| 96 | unsigned long arch_local_irq_save(void) | ||
| 97 | { | ||
| 98 | unsigned long flags; | ||
| 99 | preempt_disable(); | ||
| 100 | asm volatile("arch_local_irq_save\t%0" | ||
| 101 | : "=r" (flags) | ||
| 102 | : /* no inputs */ | ||
| 103 | : "memory"); | ||
| 104 | preempt_enable(); | ||
| 105 | return flags; | ||
| 106 | } | ||
| 107 | EXPORT_SYMBOL(arch_local_irq_save); | ||
| 108 | |||
| 109 | |||
| 110 | __asm__( | ||
| 111 | " .macro arch_local_irq_restore flags \n" | ||
| 112 | " .set push \n" | ||
| 113 | " .set noreorder \n" | ||
| 114 | " .set noat \n" | ||
| 115 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 116 | "mfc0 $1, $2, 1 \n" | ||
| 117 | "andi \\flags, 0x400 \n" | ||
| 118 | "ori $1, 0x400 \n" | ||
| 119 | "xori $1, 0x400 \n" | ||
| 120 | "or \\flags, $1 \n" | ||
| 121 | "mtc0 \\flags, $2, 1 \n" | ||
| 122 | #elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | ||
| 123 | /* see irqflags.h for inline function */ | ||
| 124 | #elif defined(CONFIG_CPU_MIPSR2) | ||
| 125 | /* see irqflags.h for inline function */ | ||
| 126 | #else | ||
| 127 | " mfc0 $1, $12 \n" | ||
| 128 | " andi \\flags, 1 \n" | ||
| 129 | " ori $1, 0x1f \n" | ||
| 130 | " xori $1, 0x1f \n" | ||
| 131 | " or \\flags, $1 \n" | ||
| 132 | " mtc0 \\flags, $12 \n" | ||
| 133 | #endif | ||
| 134 | " irq_disable_hazard \n" | ||
| 135 | " .set pop \n" | ||
| 136 | " .endm \n"); | ||
| 137 | |||
| 138 | void arch_local_irq_restore(unsigned long flags) | ||
| 139 | { | ||
| 140 | unsigned long __tmp1; | ||
| 141 | |||
| 142 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 143 | /* | ||
| 144 | * SMTC kernel needs to do a software replay of queued | ||
| 145 | * IPIs, at the cost of branch and call overhead on each | ||
| 146 | * local_irq_restore() | ||
| 147 | */ | ||
| 148 | if (unlikely(!(flags & 0x0400))) | ||
| 149 | smtc_ipi_replay(); | ||
| 150 | #endif | ||
| 151 | preempt_disable(); | ||
| 152 | __asm__ __volatile__( | ||
| 153 | "arch_local_irq_restore\t%0" | ||
| 154 | : "=r" (__tmp1) | ||
| 155 | : "0" (flags) | ||
| 156 | : "memory"); | ||
| 157 | preempt_enable(); | ||
| 158 | } | ||
| 159 | EXPORT_SYMBOL(arch_local_irq_restore); | ||
| 160 | |||
| 161 | |||
| 162 | void __arch_local_irq_restore(unsigned long flags) | ||
| 163 | { | ||
| 164 | unsigned long __tmp1; | ||
| 165 | |||
| 166 | preempt_disable(); | ||
| 167 | __asm__ __volatile__( | ||
| 168 | "arch_local_irq_restore\t%0" | ||
| 169 | : "=r" (__tmp1) | ||
| 170 | : "0" (flags) | ||
| 171 | : "memory"); | ||
| 172 | preempt_enable(); | ||
| 173 | } | ||
| 174 | EXPORT_SYMBOL(__arch_local_irq_restore); | ||
| 175 | |||
| 176 | #endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */ | ||
diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c index 80562b81f0f2..74732177851c 100644 --- a/arch/mips/mti-malta/malta-platform.c +++ b/arch/mips/mti-malta/malta-platform.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/mtd/partitions.h> | 29 | #include <linux/mtd/partitions.h> |
| 30 | #include <linux/mtd/physmap.h> | 30 | #include <linux/mtd/physmap.h> |
| 31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
| 32 | #include <asm/mips-boards/maltaint.h> | ||
| 32 | #include <mtd/mtd-abi.h> | 33 | #include <mtd/mtd-abi.h> |
| 33 | 34 | ||
| 34 | #define SMC_PORT(base, int) \ | 35 | #define SMC_PORT(base, int) \ |
| @@ -48,7 +49,7 @@ static struct plat_serial8250_port uart8250_data[] = { | |||
| 48 | SMC_PORT(0x2F8, 3), | 49 | SMC_PORT(0x2F8, 3), |
| 49 | { | 50 | { |
| 50 | .mapbase = 0x1f000900, /* The CBUS UART */ | 51 | .mapbase = 0x1f000900, /* The CBUS UART */ |
| 51 | .irq = MIPS_CPU_IRQ_BASE + 2, | 52 | .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, |
| 52 | .uartclk = 3686400, /* Twice the usual clk! */ | 53 | .uartclk = 3686400, /* Twice the usual clk! */ |
| 53 | .iotype = UPIO_MEM32, | 54 | .iotype = UPIO_MEM32, |
| 54 | .flags = CBUS_UART_FLAGS, | 55 | .flags = CBUS_UART_FLAGS, |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 5dba755a43e6..d385f396dfee 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -96,6 +96,7 @@ config S390 | |||
| 96 | select HAVE_MEMBLOCK_NODE_MAP | 96 | select HAVE_MEMBLOCK_NODE_MAP |
| 97 | select HAVE_CMPXCHG_LOCAL | 97 | select HAVE_CMPXCHG_LOCAL |
| 98 | select HAVE_CMPXCHG_DOUBLE | 98 | select HAVE_CMPXCHG_DOUBLE |
| 99 | select HAVE_ALIGNED_STRUCT_PAGE if SLUB | ||
| 99 | select HAVE_VIRT_CPU_ACCOUNTING | 100 | select HAVE_VIRT_CPU_ACCOUNTING |
| 100 | select VIRT_CPU_ACCOUNTING | 101 | select VIRT_CPU_ACCOUNTING |
| 101 | select ARCH_DISCARD_MEMBLOCK | 102 | select ARCH_DISCARD_MEMBLOCK |
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index 55bde6035216..ad2b924167d7 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h | |||
| @@ -9,6 +9,8 @@ | |||
| 9 | 9 | ||
| 10 | #define LPM_ANYPATH 0xff | 10 | #define LPM_ANYPATH 0xff |
| 11 | #define __MAX_CSSID 0 | 11 | #define __MAX_CSSID 0 |
| 12 | #define __MAX_SUBCHANNEL 65535 | ||
| 13 | #define __MAX_SSID 3 | ||
| 12 | 14 | ||
| 13 | #include <asm/scsw.h> | 15 | #include <asm/scsw.h> |
| 14 | 16 | ||
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index a34a9d612fc0..18cd6b592650 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #define PSW32_MASK_CC 0x00003000UL | 20 | #define PSW32_MASK_CC 0x00003000UL |
| 21 | #define PSW32_MASK_PM 0x00000f00UL | 21 | #define PSW32_MASK_PM 0x00000f00UL |
| 22 | 22 | ||
| 23 | #define PSW32_MASK_USER 0x00003F00UL | 23 | #define PSW32_MASK_USER 0x0000FF00UL |
| 24 | 24 | ||
| 25 | #define PSW32_ADDR_AMODE 0x80000000UL | 25 | #define PSW32_ADDR_AMODE 0x80000000UL |
| 26 | #define PSW32_ADDR_INSN 0x7FFFFFFFUL | 26 | #define PSW32_ADDR_INSN 0x7FFFFFFFUL |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index dd647c919a66..2d3b7cb26005 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
| @@ -506,12 +506,15 @@ static inline int pud_bad(pud_t pud) | |||
| 506 | 506 | ||
| 507 | static inline int pmd_present(pmd_t pmd) | 507 | static inline int pmd_present(pmd_t pmd) |
| 508 | { | 508 | { |
| 509 | return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; | 509 | unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO; |
| 510 | return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE || | ||
| 511 | !(pmd_val(pmd) & _SEGMENT_ENTRY_INV); | ||
| 510 | } | 512 | } |
| 511 | 513 | ||
| 512 | static inline int pmd_none(pmd_t pmd) | 514 | static inline int pmd_none(pmd_t pmd) |
| 513 | { | 515 | { |
| 514 | return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; | 516 | return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) && |
| 517 | !(pmd_val(pmd) & _SEGMENT_ENTRY_RO); | ||
| 515 | } | 518 | } |
| 516 | 519 | ||
| 517 | static inline int pmd_large(pmd_t pmd) | 520 | static inline int pmd_large(pmd_t pmd) |
| @@ -1223,6 +1226,11 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) | |||
| 1223 | } | 1226 | } |
| 1224 | 1227 | ||
| 1225 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 1228 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| 1229 | |||
| 1230 | #define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE) | ||
| 1231 | #define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO) | ||
| 1232 | #define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW) | ||
| 1233 | |||
| 1226 | #define __HAVE_ARCH_PGTABLE_DEPOSIT | 1234 | #define __HAVE_ARCH_PGTABLE_DEPOSIT |
| 1227 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); | 1235 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); |
| 1228 | 1236 | ||
| @@ -1242,16 +1250,15 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, | |||
| 1242 | 1250 | ||
| 1243 | static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) | 1251 | static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) |
| 1244 | { | 1252 | { |
| 1245 | unsigned long pgprot_pmd = 0; | 1253 | /* |
| 1246 | 1254 | * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx) | |
| 1247 | if (pgprot_val(pgprot) & _PAGE_INVALID) { | 1255 | * Convert to segment table entry format. |
| 1248 | if (pgprot_val(pgprot) & _PAGE_SWT) | 1256 | */ |
| 1249 | pgprot_pmd |= _HPAGE_TYPE_NONE; | 1257 | if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE)) |
| 1250 | pgprot_pmd |= _SEGMENT_ENTRY_INV; | 1258 | return pgprot_val(SEGMENT_NONE); |
| 1251 | } | 1259 | if (pgprot_val(pgprot) == pgprot_val(PAGE_RO)) |
| 1252 | if (pgprot_val(pgprot) & _PAGE_RO) | 1260 | return pgprot_val(SEGMENT_RO); |
| 1253 | pgprot_pmd |= _SEGMENT_ENTRY_RO; | 1261 | return pgprot_val(SEGMENT_RW); |
| 1254 | return pgprot_pmd; | ||
| 1255 | } | 1262 | } |
| 1256 | 1263 | ||
| 1257 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) | 1264 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) |
| @@ -1269,7 +1276,9 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) | |||
| 1269 | 1276 | ||
| 1270 | static inline pmd_t pmd_mkwrite(pmd_t pmd) | 1277 | static inline pmd_t pmd_mkwrite(pmd_t pmd) |
| 1271 | { | 1278 | { |
| 1272 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; | 1279 | /* Do not clobber _HPAGE_TYPE_NONE pages! */ |
| 1280 | if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV)) | ||
| 1281 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; | ||
| 1273 | return pmd; | 1282 | return pmd; |
| 1274 | } | 1283 | } |
| 1275 | 1284 | ||
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index 9ca305383760..9935cbd6a46f 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h | |||
| @@ -8,6 +8,9 @@ struct cpu; | |||
| 8 | 8 | ||
| 9 | #ifdef CONFIG_SCHED_BOOK | 9 | #ifdef CONFIG_SCHED_BOOK |
| 10 | 10 | ||
| 11 | extern unsigned char cpu_socket_id[NR_CPUS]; | ||
| 12 | #define topology_physical_package_id(cpu) (cpu_socket_id[cpu]) | ||
| 13 | |||
| 11 | extern unsigned char cpu_core_id[NR_CPUS]; | 14 | extern unsigned char cpu_core_id[NR_CPUS]; |
| 12 | extern cpumask_t cpu_core_map[NR_CPUS]; | 15 | extern cpumask_t cpu_core_map[NR_CPUS]; |
| 13 | 16 | ||
diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h index 705588a16d70..a5ca214b34fd 100644 --- a/arch/s390/include/uapi/asm/ptrace.h +++ b/arch/s390/include/uapi/asm/ptrace.h | |||
| @@ -239,7 +239,7 @@ typedef struct | |||
| 239 | #define PSW_MASK_EA 0x00000000UL | 239 | #define PSW_MASK_EA 0x00000000UL |
| 240 | #define PSW_MASK_BA 0x00000000UL | 240 | #define PSW_MASK_BA 0x00000000UL |
| 241 | 241 | ||
| 242 | #define PSW_MASK_USER 0x00003F00UL | 242 | #define PSW_MASK_USER 0x0000FF00UL |
| 243 | 243 | ||
| 244 | #define PSW_ADDR_AMODE 0x80000000UL | 244 | #define PSW_ADDR_AMODE 0x80000000UL |
| 245 | #define PSW_ADDR_INSN 0x7FFFFFFFUL | 245 | #define PSW_ADDR_INSN 0x7FFFFFFFUL |
| @@ -269,7 +269,7 @@ typedef struct | |||
| 269 | #define PSW_MASK_EA 0x0000000100000000UL | 269 | #define PSW_MASK_EA 0x0000000100000000UL |
| 270 | #define PSW_MASK_BA 0x0000000080000000UL | 270 | #define PSW_MASK_BA 0x0000000080000000UL |
| 271 | 271 | ||
| 272 | #define PSW_MASK_USER 0x00003F8180000000UL | 272 | #define PSW_MASK_USER 0x0000FF8180000000UL |
| 273 | 273 | ||
| 274 | #define PSW_ADDR_AMODE 0x0000000000000000UL | 274 | #define PSW_ADDR_AMODE 0x0000000000000000UL |
| 275 | #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL | 275 | #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL |
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index a1e8a8694bb7..593fcc9253fc 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
| @@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) | |||
| 309 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | | 309 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | |
| 310 | (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | | 310 | (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | |
| 311 | (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); | 311 | (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); |
| 312 | /* Check for invalid user address space control. */ | ||
| 313 | if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) | ||
| 314 | regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | | ||
| 315 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 312 | regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); | 316 | regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); |
| 313 | for (i = 0; i < NUM_GPRS; i++) | 317 | for (i = 0; i < NUM_GPRS; i++) |
| 314 | regs->gprs[i] = (__u64) regs32.gprs[i]; | 318 | regs->gprs[i] = (__u64) regs32.gprs[i]; |
| @@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct k_sigaction *ka, | |||
| 481 | 485 | ||
| 482 | /* Set up registers for signal handler */ | 486 | /* Set up registers for signal handler */ |
| 483 | regs->gprs[15] = (__force __u64) frame; | 487 | regs->gprs[15] = (__force __u64) frame; |
| 484 | regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ | 488 | /* Force 31 bit amode and default user address space control. */ |
| 489 | regs->psw.mask = PSW_MASK_BA | | ||
| 490 | (psw_user_bits & PSW_MASK_ASC) | | ||
| 491 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 485 | regs->psw.addr = (__force __u64) ka->sa.sa_handler; | 492 | regs->psw.addr = (__force __u64) ka->sa.sa_handler; |
| 486 | 493 | ||
| 487 | regs->gprs[2] = map_signal(sig); | 494 | regs->gprs[2] = map_signal(sig); |
| @@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 549 | 556 | ||
| 550 | /* Set up registers for signal handler */ | 557 | /* Set up registers for signal handler */ |
| 551 | regs->gprs[15] = (__force __u64) frame; | 558 | regs->gprs[15] = (__force __u64) frame; |
| 552 | regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ | 559 | /* Force 31 bit amode and default user address space control. */ |
| 560 | regs->psw.mask = PSW_MASK_BA | | ||
| 561 | (psw_user_bits & PSW_MASK_ASC) | | ||
| 562 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 553 | regs->psw.addr = (__u64) ka->sa.sa_handler; | 563 | regs->psw.addr = (__u64) ka->sa.sa_handler; |
| 554 | 564 | ||
| 555 | regs->gprs[2] = map_signal(sig); | 565 | regs->gprs[2] = map_signal(sig); |
diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S index bf053898630d..b6506ee32a36 100644 --- a/arch/s390/kernel/sclp.S +++ b/arch/s390/kernel/sclp.S | |||
| @@ -44,6 +44,12 @@ _sclp_wait_int: | |||
| 44 | #endif | 44 | #endif |
| 45 | mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8) | 45 | mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8) |
| 46 | mvc 0(16,%r8),0(%r9) | 46 | mvc 0(16,%r8),0(%r9) |
| 47 | #ifdef CONFIG_64BIT | ||
| 48 | epsw %r6,%r7 # set current addressing mode | ||
| 49 | nill %r6,0x1 # in new psw (31 or 64 bit mode) | ||
| 50 | nilh %r7,0x8000 | ||
| 51 | stm %r6,%r7,0(%r8) | ||
| 52 | #endif | ||
| 47 | lhi %r6,0x0200 # cr mask for ext int (cr0.54) | 53 | lhi %r6,0x0200 # cr mask for ext int (cr0.54) |
| 48 | ltr %r2,%r2 | 54 | ltr %r2,%r2 |
| 49 | jz .LsetctS1 | 55 | jz .LsetctS1 |
| @@ -87,7 +93,7 @@ _sclp_wait_int: | |||
| 87 | .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int | 93 | .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int |
| 88 | #ifdef CONFIG_64BIT | 94 | #ifdef CONFIG_64BIT |
| 89 | .LextpswS1_64: | 95 | .LextpswS1_64: |
| 90 | .quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit | 96 | .quad 0, .LwaitS1 # PSW to handle ext int, 64 bit |
| 91 | #endif | 97 | #endif |
| 92 | .LwaitpswS1: | 98 | .LwaitpswS1: |
| 93 | .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int | 99 | .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int |
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index c13a2a37ef00..d1259d875074 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
| @@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) | |||
| 136 | /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ | 136 | /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ |
| 137 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | | 137 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | |
| 138 | (user_sregs.regs.psw.mask & PSW_MASK_USER); | 138 | (user_sregs.regs.psw.mask & PSW_MASK_USER); |
| 139 | /* Check for invalid user address space control. */ | ||
| 140 | if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) | ||
| 141 | regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | | ||
| 142 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 139 | /* Check for invalid amode */ | 143 | /* Check for invalid amode */ |
| 140 | if (regs->psw.mask & PSW_MASK_EA) | 144 | if (regs->psw.mask & PSW_MASK_EA) |
| 141 | regs->psw.mask |= PSW_MASK_BA; | 145 | regs->psw.mask |= PSW_MASK_BA; |
| @@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka, | |||
| 273 | 277 | ||
| 274 | /* Set up registers for signal handler */ | 278 | /* Set up registers for signal handler */ |
| 275 | regs->gprs[15] = (unsigned long) frame; | 279 | regs->gprs[15] = (unsigned long) frame; |
| 276 | regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ | 280 | /* Force default amode and default user address space control. */ |
| 281 | regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | | ||
| 282 | (psw_user_bits & PSW_MASK_ASC) | | ||
| 283 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 277 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; | 284 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; |
| 278 | 285 | ||
| 279 | regs->gprs[2] = map_signal(sig); | 286 | regs->gprs[2] = map_signal(sig); |
| @@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 346 | 353 | ||
| 347 | /* Set up registers for signal handler */ | 354 | /* Set up registers for signal handler */ |
| 348 | regs->gprs[15] = (unsigned long) frame; | 355 | regs->gprs[15] = (unsigned long) frame; |
| 349 | regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ | 356 | /* Force default amode and default user address space control. */ |
| 357 | regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | | ||
| 358 | (psw_user_bits & PSW_MASK_ASC) | | ||
| 359 | (regs->psw.mask & ~PSW_MASK_ASC); | ||
| 350 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; | 360 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; |
| 351 | 361 | ||
| 352 | regs->gprs[2] = map_signal(sig); | 362 | regs->gprs[2] = map_signal(sig); |
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 54d93f4b6818..dd55f7c20104 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c | |||
| @@ -40,6 +40,7 @@ static DEFINE_SPINLOCK(topology_lock); | |||
| 40 | static struct mask_info core_info; | 40 | static struct mask_info core_info; |
| 41 | cpumask_t cpu_core_map[NR_CPUS]; | 41 | cpumask_t cpu_core_map[NR_CPUS]; |
| 42 | unsigned char cpu_core_id[NR_CPUS]; | 42 | unsigned char cpu_core_id[NR_CPUS]; |
| 43 | unsigned char cpu_socket_id[NR_CPUS]; | ||
| 43 | 44 | ||
| 44 | static struct mask_info book_info; | 45 | static struct mask_info book_info; |
| 45 | cpumask_t cpu_book_map[NR_CPUS]; | 46 | cpumask_t cpu_book_map[NR_CPUS]; |
| @@ -83,11 +84,12 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, | |||
| 83 | cpumask_set_cpu(lcpu, &book->mask); | 84 | cpumask_set_cpu(lcpu, &book->mask); |
| 84 | cpu_book_id[lcpu] = book->id; | 85 | cpu_book_id[lcpu] = book->id; |
| 85 | cpumask_set_cpu(lcpu, &core->mask); | 86 | cpumask_set_cpu(lcpu, &core->mask); |
| 87 | cpu_core_id[lcpu] = rcpu; | ||
| 86 | if (one_core_per_cpu) { | 88 | if (one_core_per_cpu) { |
| 87 | cpu_core_id[lcpu] = rcpu; | 89 | cpu_socket_id[lcpu] = rcpu; |
| 88 | core = core->next; | 90 | core = core->next; |
| 89 | } else { | 91 | } else { |
| 90 | cpu_core_id[lcpu] = core->id; | 92 | cpu_socket_id[lcpu] = core->id; |
| 91 | } | 93 | } |
| 92 | smp_cpu_set_polarization(lcpu, tl_cpu->pp); | 94 | smp_cpu_set_polarization(lcpu, tl_cpu->pp); |
| 93 | } | 95 | } |
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index 2d37bb861faf..9017a63dda3d 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c | |||
| @@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm, | |||
| 39 | pmd = pmd_offset(pud, addr); | 39 | pmd = pmd_offset(pud, addr); |
| 40 | if (pmd_none(*pmd)) | 40 | if (pmd_none(*pmd)) |
| 41 | return -0x10UL; | 41 | return -0x10UL; |
| 42 | if (pmd_huge(*pmd)) { | 42 | if (pmd_large(*pmd)) { |
| 43 | if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) | 43 | if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) |
| 44 | return -0x04UL; | 44 | return -0x04UL; |
| 45 | return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); | 45 | return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); |
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 60acb93a4680..1f5315d1215c 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c | |||
| @@ -126,7 +126,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr, | |||
| 126 | */ | 126 | */ |
| 127 | if (pmd_none(pmd) || pmd_trans_splitting(pmd)) | 127 | if (pmd_none(pmd) || pmd_trans_splitting(pmd)) |
| 128 | return 0; | 128 | return 0; |
| 129 | if (unlikely(pmd_huge(pmd))) { | 129 | if (unlikely(pmd_large(pmd))) { |
| 130 | if (!gup_huge_pmd(pmdp, pmd, addr, next, | 130 | if (!gup_huge_pmd(pmdp, pmd, addr, next, |
| 131 | write, pages, nr)) | 131 | write, pages, nr)) |
| 132 | return 0; | 132 | return 0; |
| @@ -180,8 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, | |||
| 180 | addr = start; | 180 | addr = start; |
| 181 | len = (unsigned long) nr_pages << PAGE_SHIFT; | 181 | len = (unsigned long) nr_pages << PAGE_SHIFT; |
| 182 | end = start + len; | 182 | end = start + len; |
| 183 | if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, | 183 | if ((end < start) || (end > TASK_SIZE)) |
| 184 | (void __user *)start, len))) | ||
| 185 | return 0; | 184 | return 0; |
| 186 | 185 | ||
| 187 | local_irq_save(flags); | 186 | local_irq_save(flags); |
| @@ -229,7 +228,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, | |||
| 229 | addr = start; | 228 | addr = start; |
| 230 | len = (unsigned long) nr_pages << PAGE_SHIFT; | 229 | len = (unsigned long) nr_pages << PAGE_SHIFT; |
| 231 | end = start + len; | 230 | end = start + len; |
| 232 | if (end < start) | 231 | if ((end < start) || (end > TASK_SIZE)) |
| 233 | goto slow_irqon; | 232 | goto slow_irqon; |
| 234 | 233 | ||
| 235 | /* | 234 | /* |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index b6b442b0d793..9f2edb5c5551 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
| @@ -20,6 +20,7 @@ config SPARC | |||
| 20 | select HAVE_ARCH_TRACEHOOK | 20 | select HAVE_ARCH_TRACEHOOK |
| 21 | select SYSCTL_EXCEPTION_TRACE | 21 | select SYSCTL_EXCEPTION_TRACE |
| 22 | select ARCH_WANT_OPTIONAL_GPIOLIB | 22 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| 23 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | ||
| 23 | select RTC_CLASS | 24 | select RTC_CLASS |
| 24 | select RTC_DRV_M48T59 | 25 | select RTC_DRV_M48T59 |
| 25 | select HAVE_IRQ_WORK | 26 | select HAVE_IRQ_WORK |
diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile index 6ae1ad5e502b..5d469d81761f 100644 --- a/arch/sparc/crypto/Makefile +++ b/arch/sparc/crypto/Makefile | |||
| @@ -13,13 +13,13 @@ obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o | |||
| 13 | 13 | ||
| 14 | obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o | 14 | obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o |
| 15 | 15 | ||
| 16 | sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o | 16 | sha1-sparc64-y := sha1_asm.o sha1_glue.o |
| 17 | sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o | 17 | sha256-sparc64-y := sha256_asm.o sha256_glue.o |
| 18 | sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o | 18 | sha512-sparc64-y := sha512_asm.o sha512_glue.o |
| 19 | md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o | 19 | md5-sparc64-y := md5_asm.o md5_glue.o |
| 20 | 20 | ||
| 21 | aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o | 21 | aes-sparc64-y := aes_asm.o aes_glue.o |
| 22 | des-sparc64-y := des_asm.o des_glue.o crop_devid.o | 22 | des-sparc64-y := des_asm.o des_glue.o |
| 23 | camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o | 23 | camellia-sparc64-y := camellia_asm.o camellia_glue.o |
| 24 | 24 | ||
| 25 | crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o crop_devid.o | 25 | crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o |
diff --git a/arch/sparc/crypto/aes_glue.c b/arch/sparc/crypto/aes_glue.c index 8f1c9980f637..3965d1d36dfa 100644 --- a/arch/sparc/crypto/aes_glue.c +++ b/arch/sparc/crypto/aes_glue.c | |||
| @@ -475,3 +475,5 @@ MODULE_LICENSE("GPL"); | |||
| 475 | MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); | 475 | MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); |
| 476 | 476 | ||
| 477 | MODULE_ALIAS("aes"); | 477 | MODULE_ALIAS("aes"); |
| 478 | |||
| 479 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/camellia_glue.c b/arch/sparc/crypto/camellia_glue.c index 42905c084299..62c89af3fd3f 100644 --- a/arch/sparc/crypto/camellia_glue.c +++ b/arch/sparc/crypto/camellia_glue.c | |||
| @@ -320,3 +320,5 @@ MODULE_LICENSE("GPL"); | |||
| 320 | MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); | 320 | MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); |
| 321 | 321 | ||
| 322 | MODULE_ALIAS("aes"); | 322 | MODULE_ALIAS("aes"); |
| 323 | |||
| 324 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/crc32c_glue.c b/arch/sparc/crypto/crc32c_glue.c index 0bd89cea8d8e..5162fad912ce 100644 --- a/arch/sparc/crypto/crc32c_glue.c +++ b/arch/sparc/crypto/crc32c_glue.c | |||
| @@ -177,3 +177,5 @@ MODULE_LICENSE("GPL"); | |||
| 177 | MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); | 177 | MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); |
| 178 | 178 | ||
| 179 | MODULE_ALIAS("crc32c"); | 179 | MODULE_ALIAS("crc32c"); |
| 180 | |||
| 181 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/des_glue.c b/arch/sparc/crypto/des_glue.c index c4940c2d3073..41524cebcc49 100644 --- a/arch/sparc/crypto/des_glue.c +++ b/arch/sparc/crypto/des_glue.c | |||
| @@ -527,3 +527,5 @@ MODULE_LICENSE("GPL"); | |||
| 527 | MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); | 527 | MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); |
| 528 | 528 | ||
| 529 | MODULE_ALIAS("des"); | 529 | MODULE_ALIAS("des"); |
| 530 | |||
| 531 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/md5_glue.c b/arch/sparc/crypto/md5_glue.c index 603d723038ce..09a9ea1dfb69 100644 --- a/arch/sparc/crypto/md5_glue.c +++ b/arch/sparc/crypto/md5_glue.c | |||
| @@ -186,3 +186,5 @@ MODULE_LICENSE("GPL"); | |||
| 186 | MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); | 186 | MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); |
| 187 | 187 | ||
| 188 | MODULE_ALIAS("md5"); | 188 | MODULE_ALIAS("md5"); |
| 189 | |||
| 190 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/sha1_glue.c b/arch/sparc/crypto/sha1_glue.c index 2bbb20bee9f1..6cd5f29e1e0d 100644 --- a/arch/sparc/crypto/sha1_glue.c +++ b/arch/sparc/crypto/sha1_glue.c | |||
| @@ -181,3 +181,5 @@ MODULE_LICENSE("GPL"); | |||
| 181 | MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); | 181 | MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); |
| 182 | 182 | ||
| 183 | MODULE_ALIAS("sha1"); | 183 | MODULE_ALIAS("sha1"); |
| 184 | |||
| 185 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/sha256_glue.c b/arch/sparc/crypto/sha256_glue.c index 591e656bd891..04f555ab2680 100644 --- a/arch/sparc/crypto/sha256_glue.c +++ b/arch/sparc/crypto/sha256_glue.c | |||
| @@ -239,3 +239,5 @@ MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 op | |||
| 239 | 239 | ||
| 240 | MODULE_ALIAS("sha224"); | 240 | MODULE_ALIAS("sha224"); |
| 241 | MODULE_ALIAS("sha256"); | 241 | MODULE_ALIAS("sha256"); |
| 242 | |||
| 243 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/crypto/sha512_glue.c b/arch/sparc/crypto/sha512_glue.c index 486f0a2b7001..f04d1994d19a 100644 --- a/arch/sparc/crypto/sha512_glue.c +++ b/arch/sparc/crypto/sha512_glue.c | |||
| @@ -224,3 +224,5 @@ MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 op | |||
| 224 | 224 | ||
| 225 | MODULE_ALIAS("sha384"); | 225 | MODULE_ALIAS("sha384"); |
| 226 | MODULE_ALIAS("sha512"); | 226 | MODULE_ALIAS("sha512"); |
| 227 | |||
| 228 | #include "crop_devid.c" | ||
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index ce35a1cf1a20..be56a244c9cf 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* atomic.h: Thankfully the V9 is at least reasonable for this | 1 | /* atomic.h: Thankfully the V9 is at least reasonable for this |
| 2 | * stuff. | 2 | * stuff. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) | 4 | * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com) |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #ifndef __ARCH_SPARC64_ATOMIC__ | 7 | #ifndef __ARCH_SPARC64_ATOMIC__ |
| @@ -106,6 +106,8 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) | |||
| 106 | 106 | ||
| 107 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 107 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
| 108 | 108 | ||
| 109 | extern long atomic64_dec_if_positive(atomic64_t *v); | ||
| 110 | |||
| 109 | /* Atomic operations are already serializing */ | 111 | /* Atomic operations are already serializing */ |
| 110 | #define smp_mb__before_atomic_dec() barrier() | 112 | #define smp_mb__before_atomic_dec() barrier() |
| 111 | #define smp_mb__after_atomic_dec() barrier() | 113 | #define smp_mb__after_atomic_dec() barrier() |
diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index db3af0d30fb1..4e02086b839c 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h | |||
| @@ -1,6 +1,46 @@ | |||
| 1 | #ifndef _SPARC64_BACKOFF_H | 1 | #ifndef _SPARC64_BACKOFF_H |
| 2 | #define _SPARC64_BACKOFF_H | 2 | #define _SPARC64_BACKOFF_H |
| 3 | 3 | ||
| 4 | /* The macros in this file implement an exponential backoff facility | ||
| 5 | * for atomic operations. | ||
| 6 | * | ||
| 7 | * When multiple threads compete on an atomic operation, it is | ||
| 8 | * possible for one thread to be continually denied a successful | ||
| 9 | * completion of the compare-and-swap instruction. Heavily | ||
| 10 | * threaded cpu implementations like Niagara can compound this | ||
| 11 | * problem even further. | ||
| 12 | * | ||
| 13 | * When an atomic operation fails and needs to be retried, we spin a | ||
| 14 | * certain number of times. At each subsequent failure of the same | ||
| 15 | * operation we double the spin count, realizing an exponential | ||
| 16 | * backoff. | ||
| 17 | * | ||
| 18 | * When we spin, we try to use an operation that will cause the | ||
| 19 | * current cpu strand to block, and therefore make the core fully | ||
| 20 | * available to any other other runnable strands. There are two | ||
| 21 | * options, based upon cpu capabilities. | ||
| 22 | * | ||
| 23 | * On all cpus prior to SPARC-T4 we do three dummy reads of the | ||
| 24 | * condition code register. Each read blocks the strand for something | ||
| 25 | * between 40 and 50 cpu cycles. | ||
| 26 | * | ||
| 27 | * For SPARC-T4 and later we have a special "pause" instruction | ||
| 28 | * available. This is implemented using writes to register %asr27. | ||
| 29 | * The cpu will block the number of cycles written into the register, | ||
| 30 | * unless a disrupting trap happens first. SPARC-T4 specifically | ||
| 31 | * implements pause with a granularity of 8 cycles. Each strand has | ||
| 32 | * an internal pause counter which decrements every 8 cycles. So the | ||
| 33 | * chip shifts the %asr27 value down by 3 bits, and writes the result | ||
| 34 | * into the pause counter. If a value smaller than 8 is written, the | ||
| 35 | * chip blocks for 1 cycle. | ||
| 36 | * | ||
| 37 | * To achieve the same amount of backoff as the three %ccr reads give | ||
| 38 | * on earlier chips, we shift the backoff value up by 7 bits. (Three | ||
| 39 | * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the | ||
| 40 | * whole amount we want to block into the pause register, rather than | ||
| 41 | * loop writing 128 each time. | ||
| 42 | */ | ||
| 43 | |||
| 4 | #define BACKOFF_LIMIT (4 * 1024) | 44 | #define BACKOFF_LIMIT (4 * 1024) |
| 5 | 45 | ||
| 6 | #ifdef CONFIG_SMP | 46 | #ifdef CONFIG_SMP |
| @@ -11,16 +51,25 @@ | |||
| 11 | #define BACKOFF_LABEL(spin_label, continue_label) \ | 51 | #define BACKOFF_LABEL(spin_label, continue_label) \ |
| 12 | spin_label | 52 | spin_label |
| 13 | 53 | ||
| 14 | #define BACKOFF_SPIN(reg, tmp, label) \ | 54 | #define BACKOFF_SPIN(reg, tmp, label) \ |
| 15 | mov reg, tmp; \ | 55 | mov reg, tmp; \ |
| 16 | 88: brnz,pt tmp, 88b; \ | 56 | 88: rd %ccr, %g0; \ |
| 17 | sub tmp, 1, tmp; \ | 57 | rd %ccr, %g0; \ |
| 18 | set BACKOFF_LIMIT, tmp; \ | 58 | rd %ccr, %g0; \ |
| 19 | cmp reg, tmp; \ | 59 | .section .pause_3insn_patch,"ax";\ |
| 20 | bg,pn %xcc, label; \ | 60 | .word 88b; \ |
| 21 | nop; \ | 61 | sllx tmp, 7, tmp; \ |
| 22 | ba,pt %xcc, label; \ | 62 | wr tmp, 0, %asr27; \ |
| 23 | sllx reg, 1, reg; | 63 | clr tmp; \ |
| 64 | .previous; \ | ||
| 65 | brnz,pt tmp, 88b; \ | ||
| 66 | sub tmp, 1, tmp; \ | ||
| 67 | set BACKOFF_LIMIT, tmp; \ | ||
| 68 | cmp reg, tmp; \ | ||
| 69 | bg,pn %xcc, label; \ | ||
| 70 | nop; \ | ||
| 71 | ba,pt %xcc, label; \ | ||
| 72 | sllx reg, 1, reg; | ||
| 24 | 73 | ||
| 25 | #else | 74 | #else |
| 26 | 75 | ||
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h index cef99fbc0a21..830502fe62b4 100644 --- a/arch/sparc/include/asm/compat.h +++ b/arch/sparc/include/asm/compat.h | |||
| @@ -232,9 +232,10 @@ static inline void __user *arch_compat_alloc_user_space(long len) | |||
| 232 | struct pt_regs *regs = current_thread_info()->kregs; | 232 | struct pt_regs *regs = current_thread_info()->kregs; |
| 233 | unsigned long usp = regs->u_regs[UREG_I6]; | 233 | unsigned long usp = regs->u_regs[UREG_I6]; |
| 234 | 234 | ||
| 235 | if (!(test_thread_flag(TIF_32BIT))) | 235 | if (test_thread_64bit_stack(usp)) |
| 236 | usp += STACK_BIAS; | 236 | usp += STACK_BIAS; |
| 237 | else | 237 | |
| 238 | if (test_thread_flag(TIF_32BIT)) | ||
| 238 | usp &= 0xffffffffUL; | 239 | usp &= 0xffffffffUL; |
| 239 | 240 | ||
| 240 | usp -= len; | 241 | usp -= len; |
diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index 4e5a483122a0..721e25f0e2ea 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h | |||
| @@ -196,7 +196,22 @@ extern unsigned long get_wchan(struct task_struct *task); | |||
| 196 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) | 196 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) |
| 197 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) | 197 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) |
| 198 | 198 | ||
| 199 | #define cpu_relax() barrier() | 199 | /* Please see the commentary in asm/backoff.h for a description of |
| 200 | * what these instructions are doing and how they have been choosen. | ||
| 201 | * To make a long story short, we are trying to yield the current cpu | ||
| 202 | * strand during busy loops. | ||
| 203 | */ | ||
| 204 | #define cpu_relax() asm volatile("\n99:\n\t" \ | ||
| 205 | "rd %%ccr, %%g0\n\t" \ | ||
| 206 | "rd %%ccr, %%g0\n\t" \ | ||
| 207 | "rd %%ccr, %%g0\n\t" \ | ||
| 208 | ".section .pause_3insn_patch,\"ax\"\n\t"\ | ||
| 209 | ".word 99b\n\t" \ | ||
| 210 | "wr %%g0, 128, %%asr27\n\t" \ | ||
| 211 | "nop\n\t" \ | ||
| 212 | "nop\n\t" \ | ||
| 213 | ".previous" \ | ||
| 214 | ::: "memory") | ||
| 200 | 215 | ||
| 201 | /* Prefetch support. This is tuned for UltraSPARC-III and later. | 216 | /* Prefetch support. This is tuned for UltraSPARC-III and later. |
| 202 | * UltraSPARC-I will treat these as nops, and UltraSPARC-II has | 217 | * UltraSPARC-I will treat these as nops, and UltraSPARC-II has |
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index c28765110706..f93003123bce 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h | |||
| @@ -63,5 +63,10 @@ extern char *of_console_options; | |||
| 63 | extern void irq_trans_init(struct device_node *dp); | 63 | extern void irq_trans_init(struct device_node *dp); |
| 64 | extern char *build_path_component(struct device_node *dp); | 64 | extern char *build_path_component(struct device_node *dp); |
| 65 | 65 | ||
| 66 | /* SPARC has a local implementation */ | ||
| 67 | extern int of_address_to_resource(struct device_node *dev, int index, | ||
| 68 | struct resource *r); | ||
| 69 | #define of_address_to_resource of_address_to_resource | ||
| 70 | |||
| 66 | #endif /* __KERNEL__ */ | 71 | #endif /* __KERNEL__ */ |
| 67 | #endif /* _SPARC_PROM_H */ | 72 | #endif /* _SPARC_PROM_H */ |
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index 4e2276631081..a3fe4dcc0aa6 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h | |||
| @@ -259,6 +259,11 @@ static inline bool test_and_clear_restore_sigmask(void) | |||
| 259 | 259 | ||
| 260 | #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) | 260 | #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) |
| 261 | 261 | ||
| 262 | #define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0) | ||
| 263 | #define test_thread_64bit_stack(__SP) \ | ||
| 264 | ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \ | ||
| 265 | false : true) | ||
| 266 | |||
| 262 | #endif /* !__ASSEMBLY__ */ | 267 | #endif /* !__ASSEMBLY__ */ |
| 263 | 268 | ||
| 264 | #endif /* __KERNEL__ */ | 269 | #endif /* __KERNEL__ */ |
diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h index 48f2807d3265..71b5a67522ab 100644 --- a/arch/sparc/include/asm/ttable.h +++ b/arch/sparc/include/asm/ttable.h | |||
| @@ -372,7 +372,9 @@ etrap_spill_fixup_64bit: \ | |||
| 372 | 372 | ||
| 373 | /* Normal 32bit spill */ | 373 | /* Normal 32bit spill */ |
| 374 | #define SPILL_2_GENERIC(ASI) \ | 374 | #define SPILL_2_GENERIC(ASI) \ |
| 375 | srl %sp, 0, %sp; \ | 375 | and %sp, 1, %g3; \ |
| 376 | brnz,pn %g3, (. - (128 + 4)); \ | ||
| 377 | srl %sp, 0, %sp; \ | ||
| 376 | stwa %l0, [%sp + %g0] ASI; \ | 378 | stwa %l0, [%sp + %g0] ASI; \ |
| 377 | mov 0x04, %g3; \ | 379 | mov 0x04, %g3; \ |
| 378 | stwa %l1, [%sp + %g3] ASI; \ | 380 | stwa %l1, [%sp + %g3] ASI; \ |
| @@ -398,14 +400,16 @@ etrap_spill_fixup_64bit: \ | |||
| 398 | stwa %i6, [%g1 + %g0] ASI; \ | 400 | stwa %i6, [%g1 + %g0] ASI; \ |
| 399 | stwa %i7, [%g1 + %g3] ASI; \ | 401 | stwa %i7, [%g1 + %g3] ASI; \ |
| 400 | saved; \ | 402 | saved; \ |
| 401 | retry; nop; nop; \ | 403 | retry; \ |
| 402 | b,a,pt %xcc, spill_fixup_dax; \ | 404 | b,a,pt %xcc, spill_fixup_dax; \ |
| 403 | b,a,pt %xcc, spill_fixup_mna; \ | 405 | b,a,pt %xcc, spill_fixup_mna; \ |
| 404 | b,a,pt %xcc, spill_fixup; | 406 | b,a,pt %xcc, spill_fixup; |
| 405 | 407 | ||
| 406 | #define SPILL_2_GENERIC_ETRAP \ | 408 | #define SPILL_2_GENERIC_ETRAP \ |
| 407 | etrap_user_spill_32bit: \ | 409 | etrap_user_spill_32bit: \ |
| 408 | srl %sp, 0, %sp; \ | 410 | and %sp, 1, %g3; \ |
| 411 | brnz,pn %g3, etrap_user_spill_64bit; \ | ||
| 412 | srl %sp, 0, %sp; \ | ||
| 409 | stwa %l0, [%sp + 0x00] %asi; \ | 413 | stwa %l0, [%sp + 0x00] %asi; \ |
| 410 | stwa %l1, [%sp + 0x04] %asi; \ | 414 | stwa %l1, [%sp + 0x04] %asi; \ |
| 411 | stwa %l2, [%sp + 0x08] %asi; \ | 415 | stwa %l2, [%sp + 0x08] %asi; \ |
| @@ -427,7 +431,7 @@ etrap_user_spill_32bit: \ | |||
| 427 | ba,pt %xcc, etrap_save; \ | 431 | ba,pt %xcc, etrap_save; \ |
| 428 | wrpr %g1, %cwp; \ | 432 | wrpr %g1, %cwp; \ |
| 429 | nop; nop; nop; nop; \ | 433 | nop; nop; nop; nop; \ |
| 430 | nop; nop; nop; nop; \ | 434 | nop; nop; \ |
| 431 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ | 435 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ |
| 432 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ | 436 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ |
| 433 | ba,a,pt %xcc, etrap_spill_fixup_32bit; | 437 | ba,a,pt %xcc, etrap_spill_fixup_32bit; |
| @@ -592,7 +596,9 @@ user_rtt_fill_64bit: \ | |||
| 592 | 596 | ||
| 593 | /* Normal 32bit fill */ | 597 | /* Normal 32bit fill */ |
| 594 | #define FILL_2_GENERIC(ASI) \ | 598 | #define FILL_2_GENERIC(ASI) \ |
| 595 | srl %sp, 0, %sp; \ | 599 | and %sp, 1, %g3; \ |
| 600 | brnz,pn %g3, (. - (128 + 4)); \ | ||
| 601 | srl %sp, 0, %sp; \ | ||
| 596 | lduwa [%sp + %g0] ASI, %l0; \ | 602 | lduwa [%sp + %g0] ASI, %l0; \ |
| 597 | mov 0x04, %g2; \ | 603 | mov 0x04, %g2; \ |
| 598 | mov 0x08, %g3; \ | 604 | mov 0x08, %g3; \ |
| @@ -616,14 +622,16 @@ user_rtt_fill_64bit: \ | |||
| 616 | lduwa [%g1 + %g3] ASI, %i6; \ | 622 | lduwa [%g1 + %g3] ASI, %i6; \ |
| 617 | lduwa [%g1 + %g5] ASI, %i7; \ | 623 | lduwa [%g1 + %g5] ASI, %i7; \ |
| 618 | restored; \ | 624 | restored; \ |
| 619 | retry; nop; nop; nop; nop; \ | 625 | retry; nop; nop; \ |
| 620 | b,a,pt %xcc, fill_fixup_dax; \ | 626 | b,a,pt %xcc, fill_fixup_dax; \ |
| 621 | b,a,pt %xcc, fill_fixup_mna; \ | 627 | b,a,pt %xcc, fill_fixup_mna; \ |
| 622 | b,a,pt %xcc, fill_fixup; | 628 | b,a,pt %xcc, fill_fixup; |
| 623 | 629 | ||
| 624 | #define FILL_2_GENERIC_RTRAP \ | 630 | #define FILL_2_GENERIC_RTRAP \ |
| 625 | user_rtt_fill_32bit: \ | 631 | user_rtt_fill_32bit: \ |
| 626 | srl %sp, 0, %sp; \ | 632 | and %sp, 1, %g3; \ |
| 633 | brnz,pn %g3, user_rtt_fill_64bit; \ | ||
| 634 | srl %sp, 0, %sp; \ | ||
| 627 | lduwa [%sp + 0x00] %asi, %l0; \ | 635 | lduwa [%sp + 0x00] %asi, %l0; \ |
| 628 | lduwa [%sp + 0x04] %asi, %l1; \ | 636 | lduwa [%sp + 0x04] %asi, %l1; \ |
| 629 | lduwa [%sp + 0x08] %asi, %l2; \ | 637 | lduwa [%sp + 0x08] %asi, %l2; \ |
| @@ -643,7 +651,7 @@ user_rtt_fill_32bit: \ | |||
| 643 | ba,pt %xcc, user_rtt_pre_restore; \ | 651 | ba,pt %xcc, user_rtt_pre_restore; \ |
| 644 | restored; \ | 652 | restored; \ |
| 645 | nop; nop; nop; nop; nop; \ | 653 | nop; nop; nop; nop; nop; \ |
| 646 | nop; nop; nop; nop; nop; \ | 654 | nop; nop; nop; \ |
| 647 | ba,a,pt %xcc, user_rtt_fill_fixup; \ | 655 | ba,a,pt %xcc, user_rtt_fill_fixup; \ |
| 648 | ba,a,pt %xcc, user_rtt_fill_fixup; \ | 656 | ba,a,pt %xcc, user_rtt_fill_fixup; \ |
| 649 | ba,a,pt %xcc, user_rtt_fill_fixup; | 657 | ba,a,pt %xcc, user_rtt_fill_fixup; |
diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index 8974ef7ae920..cac719d1bc5c 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h | |||
| @@ -405,8 +405,13 @@ | |||
| 405 | #define __NR_setns 337 | 405 | #define __NR_setns 337 |
| 406 | #define __NR_process_vm_readv 338 | 406 | #define __NR_process_vm_readv 338 |
| 407 | #define __NR_process_vm_writev 339 | 407 | #define __NR_process_vm_writev 339 |
| 408 | #define __NR_kern_features 340 | ||
| 409 | #define __NR_kcmp 341 | ||
| 408 | 410 | ||
| 409 | #define NR_syscalls 340 | 411 | #define NR_syscalls 342 |
| 412 | |||
| 413 | /* Bitmask values returned from kern_features system call. */ | ||
| 414 | #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 | ||
| 410 | 415 | ||
| 411 | #ifdef __32bit_syscall_numbers__ | 416 | #ifdef __32bit_syscall_numbers__ |
| 412 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, | 417 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, |
diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 0c218e4c0881..cc3c5cb47cda 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h | |||
| @@ -59,6 +59,13 @@ struct popc_6insn_patch_entry { | |||
| 59 | extern struct popc_6insn_patch_entry __popc_6insn_patch, | 59 | extern struct popc_6insn_patch_entry __popc_6insn_patch, |
| 60 | __popc_6insn_patch_end; | 60 | __popc_6insn_patch_end; |
| 61 | 61 | ||
| 62 | struct pause_patch_entry { | ||
| 63 | unsigned int addr; | ||
| 64 | unsigned int insns[3]; | ||
| 65 | }; | ||
| 66 | extern struct pause_patch_entry __pause_3insn_patch, | ||
| 67 | __pause_3insn_patch_end; | ||
| 68 | |||
| 62 | extern void __init per_cpu_patch(void); | 69 | extern void __init per_cpu_patch(void); |
| 63 | extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, | 70 | extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, |
| 64 | struct sun4v_1insn_patch_entry *); | 71 | struct sun4v_1insn_patch_entry *); |
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index f8b6eee40bde..87f60ee65433 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
| @@ -56,11 +56,13 @@ static inline unsigned int leon_eirq_get(int cpu) | |||
| 56 | static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) | 56 | static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) |
| 57 | { | 57 | { |
| 58 | unsigned int eirq; | 58 | unsigned int eirq; |
| 59 | struct irq_bucket *p; | ||
| 59 | int cpu = sparc_leon3_cpuid(); | 60 | int cpu = sparc_leon3_cpuid(); |
| 60 | 61 | ||
| 61 | eirq = leon_eirq_get(cpu); | 62 | eirq = leon_eirq_get(cpu); |
| 62 | if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ | 63 | p = irq_map[eirq]; |
| 63 | generic_handle_irq(irq_map[eirq]->irq); | 64 | if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */ |
| 65 | generic_handle_irq(p->irq); | ||
| 64 | } | 66 | } |
| 65 | 67 | ||
| 66 | /* The extended IRQ controller has been found, this function registers it */ | 68 | /* The extended IRQ controller has been found, this function registers it */ |
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 885a8af74064..b5c38faa4ead 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c | |||
| @@ -1762,15 +1762,25 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, | |||
| 1762 | 1762 | ||
| 1763 | ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; | 1763 | ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; |
| 1764 | do { | 1764 | do { |
| 1765 | struct sparc_stackf32 *usf, sf; | ||
| 1766 | unsigned long pc; | 1765 | unsigned long pc; |
| 1767 | 1766 | ||
| 1768 | usf = (struct sparc_stackf32 *) ufp; | 1767 | if (thread32_stack_is_64bit(ufp)) { |
| 1769 | if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | 1768 | struct sparc_stackf *usf, sf; |
| 1770 | break; | ||
| 1771 | 1769 | ||
| 1772 | pc = sf.callers_pc; | 1770 | ufp += STACK_BIAS; |
| 1773 | ufp = (unsigned long)sf.fp; | 1771 | usf = (struct sparc_stackf *) ufp; |
| 1772 | if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | ||
| 1773 | break; | ||
| 1774 | pc = sf.callers_pc & 0xffffffff; | ||
| 1775 | ufp = ((unsigned long) sf.fp) & 0xffffffff; | ||
| 1776 | } else { | ||
| 1777 | struct sparc_stackf32 *usf, sf; | ||
| 1778 | usf = (struct sparc_stackf32 *) ufp; | ||
| 1779 | if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | ||
| 1780 | break; | ||
| 1781 | pc = sf.callers_pc; | ||
| 1782 | ufp = (unsigned long)sf.fp; | ||
| 1783 | } | ||
| 1774 | perf_callchain_store(entry, pc); | 1784 | perf_callchain_store(entry, pc); |
| 1775 | } while (entry->nr < PERF_MAX_STACK_DEPTH); | 1785 | } while (entry->nr < PERF_MAX_STACK_DEPTH); |
| 1776 | } | 1786 | } |
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index d778248ef3f8..c6e0c2910043 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
| @@ -452,13 +452,16 @@ void flush_thread(void) | |||
| 452 | /* It's a bit more tricky when 64-bit tasks are involved... */ | 452 | /* It's a bit more tricky when 64-bit tasks are involved... */ |
| 453 | static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) | 453 | static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) |
| 454 | { | 454 | { |
| 455 | bool stack_64bit = test_thread_64bit_stack(psp); | ||
| 455 | unsigned long fp, distance, rval; | 456 | unsigned long fp, distance, rval; |
| 456 | 457 | ||
| 457 | if (!(test_thread_flag(TIF_32BIT))) { | 458 | if (stack_64bit) { |
| 458 | csp += STACK_BIAS; | 459 | csp += STACK_BIAS; |
| 459 | psp += STACK_BIAS; | 460 | psp += STACK_BIAS; |
| 460 | __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); | 461 | __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); |
| 461 | fp += STACK_BIAS; | 462 | fp += STACK_BIAS; |
| 463 | if (test_thread_flag(TIF_32BIT)) | ||
| 464 | fp &= 0xffffffff; | ||
| 462 | } else | 465 | } else |
| 463 | __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); | 466 | __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); |
| 464 | 467 | ||
| @@ -472,7 +475,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) | |||
| 472 | rval = (csp - distance); | 475 | rval = (csp - distance); |
| 473 | if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) | 476 | if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) |
| 474 | rval = 0; | 477 | rval = 0; |
| 475 | else if (test_thread_flag(TIF_32BIT)) { | 478 | else if (!stack_64bit) { |
| 476 | if (put_user(((u32)csp), | 479 | if (put_user(((u32)csp), |
| 477 | &(((struct reg_window32 __user *)rval)->ins[6]))) | 480 | &(((struct reg_window32 __user *)rval)->ins[6]))) |
| 478 | rval = 0; | 481 | rval = 0; |
| @@ -507,18 +510,18 @@ void synchronize_user_stack(void) | |||
| 507 | 510 | ||
| 508 | flush_user_windows(); | 511 | flush_user_windows(); |
| 509 | if ((window = get_thread_wsaved()) != 0) { | 512 | if ((window = get_thread_wsaved()) != 0) { |
| 510 | int winsize = sizeof(struct reg_window); | ||
| 511 | int bias = 0; | ||
| 512 | |||
| 513 | if (test_thread_flag(TIF_32BIT)) | ||
| 514 | winsize = sizeof(struct reg_window32); | ||
| 515 | else | ||
| 516 | bias = STACK_BIAS; | ||
| 517 | |||
| 518 | window -= 1; | 513 | window -= 1; |
| 519 | do { | 514 | do { |
| 520 | unsigned long sp = (t->rwbuf_stkptrs[window] + bias); | ||
| 521 | struct reg_window *rwin = &t->reg_window[window]; | 515 | struct reg_window *rwin = &t->reg_window[window]; |
| 516 | int winsize = sizeof(struct reg_window); | ||
| 517 | unsigned long sp; | ||
| 518 | |||
| 519 | sp = t->rwbuf_stkptrs[window]; | ||
| 520 | |||
| 521 | if (test_thread_64bit_stack(sp)) | ||
| 522 | sp += STACK_BIAS; | ||
| 523 | else | ||
| 524 | winsize = sizeof(struct reg_window32); | ||
| 522 | 525 | ||
| 523 | if (!copy_to_user((char __user *)sp, rwin, winsize)) { | 526 | if (!copy_to_user((char __user *)sp, rwin, winsize)) { |
| 524 | shift_window_buffer(window, get_thread_wsaved() - 1, t); | 527 | shift_window_buffer(window, get_thread_wsaved() - 1, t); |
| @@ -544,13 +547,6 @@ void fault_in_user_windows(void) | |||
| 544 | { | 547 | { |
| 545 | struct thread_info *t = current_thread_info(); | 548 | struct thread_info *t = current_thread_info(); |
| 546 | unsigned long window; | 549 | unsigned long window; |
| 547 | int winsize = sizeof(struct reg_window); | ||
| 548 | int bias = 0; | ||
| 549 | |||
| 550 | if (test_thread_flag(TIF_32BIT)) | ||
| 551 | winsize = sizeof(struct reg_window32); | ||
| 552 | else | ||
| 553 | bias = STACK_BIAS; | ||
| 554 | 550 | ||
| 555 | flush_user_windows(); | 551 | flush_user_windows(); |
| 556 | window = get_thread_wsaved(); | 552 | window = get_thread_wsaved(); |
| @@ -558,8 +554,16 @@ void fault_in_user_windows(void) | |||
| 558 | if (likely(window != 0)) { | 554 | if (likely(window != 0)) { |
| 559 | window -= 1; | 555 | window -= 1; |
| 560 | do { | 556 | do { |
| 561 | unsigned long sp = (t->rwbuf_stkptrs[window] + bias); | ||
| 562 | struct reg_window *rwin = &t->reg_window[window]; | 557 | struct reg_window *rwin = &t->reg_window[window]; |
| 558 | int winsize = sizeof(struct reg_window); | ||
| 559 | unsigned long sp; | ||
| 560 | |||
| 561 | sp = t->rwbuf_stkptrs[window]; | ||
| 562 | |||
| 563 | if (test_thread_64bit_stack(sp)) | ||
| 564 | sp += STACK_BIAS; | ||
| 565 | else | ||
| 566 | winsize = sizeof(struct reg_window32); | ||
| 563 | 567 | ||
| 564 | if (unlikely(sp & 0x7UL)) | 568 | if (unlikely(sp & 0x7UL)) |
| 565 | stack_unaligned(sp); | 569 | stack_unaligned(sp); |
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 484dabac7045..7ff45e4ba681 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c | |||
| @@ -151,7 +151,7 @@ static int regwindow64_get(struct task_struct *target, | |||
| 151 | { | 151 | { |
| 152 | unsigned long rw_addr = regs->u_regs[UREG_I6]; | 152 | unsigned long rw_addr = regs->u_regs[UREG_I6]; |
| 153 | 153 | ||
| 154 | if (test_tsk_thread_flag(current, TIF_32BIT)) { | 154 | if (!test_thread_64bit_stack(rw_addr)) { |
| 155 | struct reg_window32 win32; | 155 | struct reg_window32 win32; |
| 156 | int i; | 156 | int i; |
| 157 | 157 | ||
| @@ -176,7 +176,7 @@ static int regwindow64_set(struct task_struct *target, | |||
| 176 | { | 176 | { |
| 177 | unsigned long rw_addr = regs->u_regs[UREG_I6]; | 177 | unsigned long rw_addr = regs->u_regs[UREG_I6]; |
| 178 | 178 | ||
| 179 | if (test_tsk_thread_flag(current, TIF_32BIT)) { | 179 | if (!test_thread_64bit_stack(rw_addr)) { |
| 180 | struct reg_window32 win32; | 180 | struct reg_window32 win32; |
| 181 | int i; | 181 | int i; |
| 182 | 182 | ||
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 0800e71d8a88..0eaf0059aaef 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c | |||
| @@ -316,6 +316,25 @@ static void __init popc_patch(void) | |||
| 316 | } | 316 | } |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | static void __init pause_patch(void) | ||
| 320 | { | ||
| 321 | struct pause_patch_entry *p; | ||
| 322 | |||
| 323 | p = &__pause_3insn_patch; | ||
| 324 | while (p < &__pause_3insn_patch_end) { | ||
| 325 | unsigned long i, addr = p->addr; | ||
| 326 | |||
| 327 | for (i = 0; i < 3; i++) { | ||
| 328 | *(unsigned int *) (addr + (i * 4)) = p->insns[i]; | ||
| 329 | wmb(); | ||
| 330 | __asm__ __volatile__("flush %0" | ||
| 331 | : : "r" (addr + (i * 4))); | ||
| 332 | } | ||
| 333 | |||
| 334 | p++; | ||
| 335 | } | ||
| 336 | } | ||
| 337 | |||
| 319 | #ifdef CONFIG_SMP | 338 | #ifdef CONFIG_SMP |
| 320 | void __init boot_cpu_id_too_large(int cpu) | 339 | void __init boot_cpu_id_too_large(int cpu) |
| 321 | { | 340 | { |
| @@ -528,6 +547,8 @@ static void __init init_sparc64_elf_hwcap(void) | |||
| 528 | 547 | ||
| 529 | if (sparc64_elf_hwcap & AV_SPARC_POPC) | 548 | if (sparc64_elf_hwcap & AV_SPARC_POPC) |
| 530 | popc_patch(); | 549 | popc_patch(); |
| 550 | if (sparc64_elf_hwcap & AV_SPARC_PAUSE) | ||
| 551 | pause_patch(); | ||
| 531 | } | 552 | } |
| 532 | 553 | ||
| 533 | void __init setup_arch(char **cmdline_p) | 554 | void __init setup_arch(char **cmdline_p) |
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 11c6c9603e71..878ef3d5fec5 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
| @@ -751,3 +751,8 @@ int kernel_execve(const char *filename, | |||
| 751 | : "cc"); | 751 | : "cc"); |
| 752 | return __res; | 752 | return __res; |
| 753 | } | 753 | } |
| 754 | |||
| 755 | asmlinkage long sys_kern_features(void) | ||
| 756 | { | ||
| 757 | return KERN_FEATURE_MIXED_MODE_STACK; | ||
| 758 | } | ||
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 63402f9e9f51..5147f574f125 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S | |||
| @@ -85,3 +85,4 @@ sys_call_table: | |||
| 85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init | 85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
| 86 | /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime | 86 | /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime |
| 87 | /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev | 87 | /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev |
| 88 | /*340*/ .long sys_ni_syscall, sys_kcmp | ||
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 3a58e0d66f51..1c9af9fa38e9 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S | |||
| @@ -86,6 +86,7 @@ sys_call_table32: | |||
| 86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init | 86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init |
| 87 | /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime | 87 | /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime |
| 88 | .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev | 88 | .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev |
| 89 | /*340*/ .word sys_kern_features, sys_kcmp | ||
| 89 | 90 | ||
| 90 | #endif /* CONFIG_COMPAT */ | 91 | #endif /* CONFIG_COMPAT */ |
| 91 | 92 | ||
| @@ -163,3 +164,4 @@ sys_call_table: | |||
| 163 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init | 164 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
| 164 | /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime | 165 | /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime |
| 165 | .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev | 166 | .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev |
| 167 | /*340*/ .word sys_kern_features, sys_kcmp | ||
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index f81d038f7340..8201c25e7669 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c | |||
| @@ -113,21 +113,24 @@ static inline long sign_extend_imm13(long imm) | |||
| 113 | 113 | ||
| 114 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) | 114 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) |
| 115 | { | 115 | { |
| 116 | unsigned long value; | 116 | unsigned long value, fp; |
| 117 | 117 | ||
| 118 | if (reg < 16) | 118 | if (reg < 16) |
| 119 | return (!reg ? 0 : regs->u_regs[reg]); | 119 | return (!reg ? 0 : regs->u_regs[reg]); |
| 120 | |||
| 121 | fp = regs->u_regs[UREG_FP]; | ||
| 122 | |||
| 120 | if (regs->tstate & TSTATE_PRIV) { | 123 | if (regs->tstate & TSTATE_PRIV) { |
| 121 | struct reg_window *win; | 124 | struct reg_window *win; |
| 122 | win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 125 | win = (struct reg_window *)(fp + STACK_BIAS); |
| 123 | value = win->locals[reg - 16]; | 126 | value = win->locals[reg - 16]; |
| 124 | } else if (test_thread_flag(TIF_32BIT)) { | 127 | } else if (!test_thread_64bit_stack(fp)) { |
| 125 | struct reg_window32 __user *win32; | 128 | struct reg_window32 __user *win32; |
| 126 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 129 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); |
| 127 | get_user(value, &win32->locals[reg - 16]); | 130 | get_user(value, &win32->locals[reg - 16]); |
| 128 | } else { | 131 | } else { |
| 129 | struct reg_window __user *win; | 132 | struct reg_window __user *win; |
| 130 | win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 133 | win = (struct reg_window __user *)(fp + STACK_BIAS); |
| 131 | get_user(value, &win->locals[reg - 16]); | 134 | get_user(value, &win->locals[reg - 16]); |
| 132 | } | 135 | } |
| 133 | return value; | 136 | return value; |
| @@ -135,19 +138,24 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) | |||
| 135 | 138 | ||
| 136 | static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) | 139 | static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) |
| 137 | { | 140 | { |
| 141 | unsigned long fp; | ||
| 142 | |||
| 138 | if (reg < 16) | 143 | if (reg < 16) |
| 139 | return ®s->u_regs[reg]; | 144 | return ®s->u_regs[reg]; |
| 145 | |||
| 146 | fp = regs->u_regs[UREG_FP]; | ||
| 147 | |||
| 140 | if (regs->tstate & TSTATE_PRIV) { | 148 | if (regs->tstate & TSTATE_PRIV) { |
| 141 | struct reg_window *win; | 149 | struct reg_window *win; |
| 142 | win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 150 | win = (struct reg_window *)(fp + STACK_BIAS); |
| 143 | return &win->locals[reg - 16]; | 151 | return &win->locals[reg - 16]; |
| 144 | } else if (test_thread_flag(TIF_32BIT)) { | 152 | } else if (!test_thread_64bit_stack(fp)) { |
| 145 | struct reg_window32 *win32; | 153 | struct reg_window32 *win32; |
| 146 | win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 154 | win32 = (struct reg_window32 *)((unsigned long)((u32)fp)); |
| 147 | return (unsigned long *)&win32->locals[reg - 16]; | 155 | return (unsigned long *)&win32->locals[reg - 16]; |
| 148 | } else { | 156 | } else { |
| 149 | struct reg_window *win; | 157 | struct reg_window *win; |
| 150 | win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 158 | win = (struct reg_window *)(fp + STACK_BIAS); |
| 151 | return &win->locals[reg - 16]; | 159 | return &win->locals[reg - 16]; |
| 152 | } | 160 | } |
| 153 | } | 161 | } |
| @@ -392,13 +400,15 @@ int handle_popc(u32 insn, struct pt_regs *regs) | |||
| 392 | if (rd) | 400 | if (rd) |
| 393 | regs->u_regs[rd] = ret; | 401 | regs->u_regs[rd] = ret; |
| 394 | } else { | 402 | } else { |
| 395 | if (test_thread_flag(TIF_32BIT)) { | 403 | unsigned long fp = regs->u_regs[UREG_FP]; |
| 404 | |||
| 405 | if (!test_thread_64bit_stack(fp)) { | ||
| 396 | struct reg_window32 __user *win32; | 406 | struct reg_window32 __user *win32; |
| 397 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 407 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); |
| 398 | put_user(ret, &win32->locals[rd - 16]); | 408 | put_user(ret, &win32->locals[rd - 16]); |
| 399 | } else { | 409 | } else { |
| 400 | struct reg_window __user *win; | 410 | struct reg_window __user *win; |
| 401 | win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 411 | win = (struct reg_window __user *)(fp + STACK_BIAS); |
| 402 | put_user(ret, &win->locals[rd - 16]); | 412 | put_user(ret, &win->locals[rd - 16]); |
| 403 | } | 413 | } |
| 404 | } | 414 | } |
| @@ -554,7 +564,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) | |||
| 554 | reg[0] = 0; | 564 | reg[0] = 0; |
| 555 | if ((insn & 0x780000) == 0x180000) | 565 | if ((insn & 0x780000) == 0x180000) |
| 556 | reg[1] = 0; | 566 | reg[1] = 0; |
| 557 | } else if (test_thread_flag(TIF_32BIT)) { | 567 | } else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { |
| 558 | put_user(0, (int __user *) reg); | 568 | put_user(0, (int __user *) reg); |
| 559 | if ((insn & 0x780000) == 0x180000) | 569 | if ((insn & 0x780000) == 0x180000) |
| 560 | put_user(0, ((int __user *) reg) + 1); | 570 | put_user(0, ((int __user *) reg) + 1); |
diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c index 08e074b7eb6a..c096c624ac4d 100644 --- a/arch/sparc/kernel/visemul.c +++ b/arch/sparc/kernel/visemul.c | |||
| @@ -149,21 +149,24 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, | |||
| 149 | 149 | ||
| 150 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) | 150 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) |
| 151 | { | 151 | { |
| 152 | unsigned long value; | 152 | unsigned long value, fp; |
| 153 | 153 | ||
| 154 | if (reg < 16) | 154 | if (reg < 16) |
| 155 | return (!reg ? 0 : regs->u_regs[reg]); | 155 | return (!reg ? 0 : regs->u_regs[reg]); |
| 156 | |||
| 157 | fp = regs->u_regs[UREG_FP]; | ||
| 158 | |||
| 156 | if (regs->tstate & TSTATE_PRIV) { | 159 | if (regs->tstate & TSTATE_PRIV) { |
| 157 | struct reg_window *win; | 160 | struct reg_window *win; |
| 158 | win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 161 | win = (struct reg_window *)(fp + STACK_BIAS); |
| 159 | value = win->locals[reg - 16]; | 162 | value = win->locals[reg - 16]; |
| 160 | } else if (test_thread_flag(TIF_32BIT)) { | 163 | } else if (!test_thread_64bit_stack(fp)) { |
| 161 | struct reg_window32 __user *win32; | 164 | struct reg_window32 __user *win32; |
| 162 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 165 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); |
| 163 | get_user(value, &win32->locals[reg - 16]); | 166 | get_user(value, &win32->locals[reg - 16]); |
| 164 | } else { | 167 | } else { |
| 165 | struct reg_window __user *win; | 168 | struct reg_window __user *win; |
| 166 | win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 169 | win = (struct reg_window __user *)(fp + STACK_BIAS); |
| 167 | get_user(value, &win->locals[reg - 16]); | 170 | get_user(value, &win->locals[reg - 16]); |
| 168 | } | 171 | } |
| 169 | return value; | 172 | return value; |
| @@ -172,16 +175,18 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) | |||
| 172 | static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, | 175 | static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, |
| 173 | struct pt_regs *regs) | 176 | struct pt_regs *regs) |
| 174 | { | 177 | { |
| 178 | unsigned long fp = regs->u_regs[UREG_FP]; | ||
| 179 | |||
| 175 | BUG_ON(reg < 16); | 180 | BUG_ON(reg < 16); |
| 176 | BUG_ON(regs->tstate & TSTATE_PRIV); | 181 | BUG_ON(regs->tstate & TSTATE_PRIV); |
| 177 | 182 | ||
| 178 | if (test_thread_flag(TIF_32BIT)) { | 183 | if (!test_thread_64bit_stack(fp)) { |
| 179 | struct reg_window32 __user *win32; | 184 | struct reg_window32 __user *win32; |
| 180 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 185 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); |
| 181 | return (unsigned long __user *)&win32->locals[reg - 16]; | 186 | return (unsigned long __user *)&win32->locals[reg - 16]; |
| 182 | } else { | 187 | } else { |
| 183 | struct reg_window __user *win; | 188 | struct reg_window __user *win; |
| 184 | win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | 189 | win = (struct reg_window __user *)(fp + STACK_BIAS); |
| 185 | return &win->locals[reg - 16]; | 190 | return &win->locals[reg - 16]; |
| 186 | } | 191 | } |
| 187 | } | 192 | } |
| @@ -204,7 +209,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd) | |||
| 204 | } else { | 209 | } else { |
| 205 | unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); | 210 | unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); |
| 206 | 211 | ||
| 207 | if (test_thread_flag(TIF_32BIT)) | 212 | if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) |
| 208 | __put_user((u32)val, (u32 __user *)rd_user); | 213 | __put_user((u32)val, (u32 __user *)rd_user); |
| 209 | else | 214 | else |
| 210 | __put_user(val, rd_user); | 215 | __put_user(val, rd_user); |
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 89c2c29f154b..0bacceb19150 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S | |||
| @@ -132,6 +132,11 @@ SECTIONS | |||
| 132 | *(.popc_6insn_patch) | 132 | *(.popc_6insn_patch) |
| 133 | __popc_6insn_patch_end = .; | 133 | __popc_6insn_patch_end = .; |
| 134 | } | 134 | } |
| 135 | .pause_3insn_patch : { | ||
| 136 | __pause_3insn_patch = .; | ||
| 137 | *(.pause_3insn_patch) | ||
| 138 | __pause_3insn_patch_end = .; | ||
| 139 | } | ||
| 135 | PERCPU_SECTION(SMP_CACHE_BYTES) | 140 | PERCPU_SECTION(SMP_CACHE_BYTES) |
| 136 | 141 | ||
| 137 | . = ALIGN(PAGE_SIZE); | 142 | . = ALIGN(PAGE_SIZE); |
diff --git a/arch/sparc/kernel/winfixup.S b/arch/sparc/kernel/winfixup.S index a6b0863c27df..1e67ce958369 100644 --- a/arch/sparc/kernel/winfixup.S +++ b/arch/sparc/kernel/winfixup.S | |||
| @@ -43,6 +43,8 @@ spill_fixup_mna: | |||
| 43 | spill_fixup_dax: | 43 | spill_fixup_dax: |
| 44 | TRAP_LOAD_THREAD_REG(%g6, %g1) | 44 | TRAP_LOAD_THREAD_REG(%g6, %g1) |
| 45 | ldx [%g6 + TI_FLAGS], %g1 | 45 | ldx [%g6 + TI_FLAGS], %g1 |
| 46 | andcc %sp, 0x1, %g0 | ||
| 47 | movne %icc, 0, %g1 | ||
| 46 | andcc %g1, _TIF_32BIT, %g0 | 48 | andcc %g1, _TIF_32BIT, %g0 |
| 47 | ldub [%g6 + TI_WSAVED], %g1 | 49 | ldub [%g6 + TI_WSAVED], %g1 |
| 48 | sll %g1, 3, %g3 | 50 | sll %g1, 3, %g3 |
diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S index 4d502da3de78..85c233d0a340 100644 --- a/arch/sparc/lib/atomic_64.S +++ b/arch/sparc/lib/atomic_64.S | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* atomic.S: These things are too big to do inline. | 1 | /* atomic.S: These things are too big to do inline. |
| 2 | * | 2 | * |
| 3 | * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) | 3 | * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net) |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <linux/linkage.h> | 6 | #include <linux/linkage.h> |
| @@ -117,3 +117,17 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ | |||
| 117 | sub %g1, %o0, %o0 | 117 | sub %g1, %o0, %o0 |
| 118 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 118 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
| 119 | ENDPROC(atomic64_sub_ret) | 119 | ENDPROC(atomic64_sub_ret) |
| 120 | |||
| 121 | ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */ | ||
| 122 | BACKOFF_SETUP(%o2) | ||
| 123 | 1: ldx [%o0], %g1 | ||
| 124 | brlez,pn %g1, 3f | ||
| 125 | sub %g1, 1, %g7 | ||
| 126 | casx [%o0], %g1, %g7 | ||
| 127 | cmp %g1, %g7 | ||
| 128 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) | ||
| 129 | nop | ||
| 130 | 3: retl | ||
| 131 | sub %g1, 1, %o0 | ||
| 132 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | ||
| 133 | ENDPROC(atomic64_dec_if_positive) | ||
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c index ee31b884c61b..0c4e35e522fa 100644 --- a/arch/sparc/lib/ksyms.c +++ b/arch/sparc/lib/ksyms.c | |||
| @@ -116,6 +116,7 @@ EXPORT_SYMBOL(atomic64_add); | |||
| 116 | EXPORT_SYMBOL(atomic64_add_ret); | 116 | EXPORT_SYMBOL(atomic64_add_ret); |
| 117 | EXPORT_SYMBOL(atomic64_sub); | 117 | EXPORT_SYMBOL(atomic64_sub); |
| 118 | EXPORT_SYMBOL(atomic64_sub_ret); | 118 | EXPORT_SYMBOL(atomic64_sub_ret); |
| 119 | EXPORT_SYMBOL(atomic64_dec_if_positive); | ||
| 119 | 120 | ||
| 120 | /* Atomic bit operations. */ | 121 | /* Atomic bit operations. */ |
| 121 | EXPORT_SYMBOL(test_and_set_bit); | 122 | EXPORT_SYMBOL(test_and_set_bit); |
diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c index 1704068da928..034aadbff036 100644 --- a/arch/sparc/math-emu/math_64.c +++ b/arch/sparc/math-emu/math_64.c | |||
| @@ -320,7 +320,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) | |||
| 320 | XR = 0; | 320 | XR = 0; |
| 321 | else if (freg < 16) | 321 | else if (freg < 16) |
| 322 | XR = regs->u_regs[freg]; | 322 | XR = regs->u_regs[freg]; |
| 323 | else if (test_thread_flag(TIF_32BIT)) { | 323 | else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { |
| 324 | struct reg_window32 __user *win32; | 324 | struct reg_window32 __user *win32; |
| 325 | flushw_user (); | 325 | flushw_user (); |
| 326 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | 326 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); |
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index e5c5473e69ce..c4fbb21e802b 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig | |||
| @@ -16,6 +16,8 @@ config UNICORE32 | |||
| 16 | select ARCH_WANT_FRAME_POINTERS | 16 | select ARCH_WANT_FRAME_POINTERS |
| 17 | select GENERIC_IOMAP | 17 | select GENERIC_IOMAP |
| 18 | select MODULES_USE_ELF_REL | 18 | select MODULES_USE_ELF_REL |
| 19 | select GENERIC_KERNEL_THREAD | ||
| 20 | select GENERIC_KERNEL_EXECVE | ||
| 19 | help | 21 | help |
| 20 | UniCore-32 is 32-bit Instruction Set Architecture, | 22 | UniCore-32 is 32-bit Instruction Set Architecture, |
| 21 | including a series of low-power-consumption RISC chip | 23 | including a series of low-power-consumption RISC chip |
| @@ -64,6 +66,9 @@ config GENERIC_CALIBRATE_DELAY | |||
| 64 | config ARCH_MAY_HAVE_PC_FDC | 66 | config ARCH_MAY_HAVE_PC_FDC |
| 65 | bool | 67 | bool |
| 66 | 68 | ||
| 69 | config ZONE_DMA | ||
| 70 | def_bool y | ||
| 71 | |||
| 67 | config NEED_DMA_MAP_STATE | 72 | config NEED_DMA_MAP_STATE |
| 68 | def_bool y | 73 | def_bool y |
| 69 | 74 | ||
| @@ -216,7 +221,7 @@ config PUV3_GPIO | |||
| 216 | bool | 221 | bool |
| 217 | depends on !ARCH_FPGA | 222 | depends on !ARCH_FPGA |
| 218 | select GENERIC_GPIO | 223 | select GENERIC_GPIO |
| 219 | select GPIO_SYSFS if EXPERIMENTAL | 224 | select GPIO_SYSFS |
| 220 | default y | 225 | default y |
| 221 | 226 | ||
| 222 | if PUV3_NB0916 | 227 | if PUV3_NB0916 |
diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index c910c9857e11..601e92f18af6 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild | |||
| @@ -1,4 +1,3 @@ | |||
| 1 | include include/asm-generic/Kbuild.asm | ||
| 2 | 1 | ||
| 3 | generic-y += atomic.h | 2 | generic-y += atomic.h |
| 4 | generic-y += auxvec.h | 3 | generic-y += auxvec.h |
diff --git a/arch/unicore32/include/asm/bug.h b/arch/unicore32/include/asm/bug.h index b1ff8cadb086..93a56f3e2344 100644 --- a/arch/unicore32/include/asm/bug.h +++ b/arch/unicore32/include/asm/bug.h | |||
| @@ -19,9 +19,4 @@ extern void die(const char *msg, struct pt_regs *regs, int err); | |||
| 19 | extern void uc32_notify_die(const char *str, struct pt_regs *regs, | 19 | extern void uc32_notify_die(const char *str, struct pt_regs *regs, |
| 20 | struct siginfo *info, unsigned long err, unsigned long trap); | 20 | struct siginfo *info, unsigned long err, unsigned long trap); |
| 21 | 21 | ||
| 22 | extern asmlinkage void __backtrace(void); | ||
| 23 | extern asmlinkage void c_backtrace(unsigned long fp, int pmode); | ||
| 24 | |||
| 25 | extern void __show_regs(struct pt_regs *); | ||
| 26 | |||
| 27 | #endif /* __UNICORE_BUG_H__ */ | 22 | #endif /* __UNICORE_BUG_H__ */ |
diff --git a/arch/unicore32/include/asm/cmpxchg.h b/arch/unicore32/include/asm/cmpxchg.h index df4d5acfd19f..8e797ad4fa24 100644 --- a/arch/unicore32/include/asm/cmpxchg.h +++ b/arch/unicore32/include/asm/cmpxchg.h | |||
| @@ -35,7 +35,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, | |||
| 35 | : "memory", "cc"); | 35 | : "memory", "cc"); |
| 36 | break; | 36 | break; |
| 37 | default: | 37 | default: |
| 38 | ret = __xchg_bad_pointer(); | 38 | __xchg_bad_pointer(); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | return ret; | 41 | return ret; |
diff --git a/arch/unicore32/include/asm/kvm_para.h b/arch/unicore32/include/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b957..000000000000 --- a/arch/unicore32/include/asm/kvm_para.h +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | #include <asm-generic/kvm_para.h> | ||
diff --git a/arch/unicore32/include/asm/processor.h b/arch/unicore32/include/asm/processor.h index 14382cb09657..4eaa42167667 100644 --- a/arch/unicore32/include/asm/processor.h +++ b/arch/unicore32/include/asm/processor.h | |||
| @@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p); | |||
| 72 | 72 | ||
| 73 | #define cpu_relax() barrier() | 73 | #define cpu_relax() barrier() |
| 74 | 74 | ||
| 75 | /* | ||
| 76 | * Create a new kernel thread | ||
| 77 | */ | ||
| 78 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); | ||
| 79 | |||
| 80 | #define task_pt_regs(p) \ | 75 | #define task_pt_regs(p) \ |
| 81 | ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) | 76 | ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) |
| 82 | 77 | ||
diff --git a/arch/unicore32/include/asm/ptrace.h b/arch/unicore32/include/asm/ptrace.h index b9caf9b0997b..726749dab52f 100644 --- a/arch/unicore32/include/asm/ptrace.h +++ b/arch/unicore32/include/asm/ptrace.h | |||
| @@ -12,80 +12,10 @@ | |||
| 12 | #ifndef __UNICORE_PTRACE_H__ | 12 | #ifndef __UNICORE_PTRACE_H__ |
| 13 | #define __UNICORE_PTRACE_H__ | 13 | #define __UNICORE_PTRACE_H__ |
| 14 | 14 | ||
| 15 | #define PTRACE_GET_THREAD_AREA 22 | 15 | #include <uapi/asm/ptrace.h> |
| 16 | |||
| 17 | /* | ||
| 18 | * PSR bits | ||
| 19 | */ | ||
| 20 | #define USER_MODE 0x00000010 | ||
| 21 | #define REAL_MODE 0x00000011 | ||
| 22 | #define INTR_MODE 0x00000012 | ||
| 23 | #define PRIV_MODE 0x00000013 | ||
| 24 | #define ABRT_MODE 0x00000017 | ||
| 25 | #define EXTN_MODE 0x0000001b | ||
| 26 | #define SUSR_MODE 0x0000001f | ||
| 27 | #define MODE_MASK 0x0000001f | ||
| 28 | #define PSR_R_BIT 0x00000040 | ||
| 29 | #define PSR_I_BIT 0x00000080 | ||
| 30 | #define PSR_V_BIT 0x10000000 | ||
| 31 | #define PSR_C_BIT 0x20000000 | ||
| 32 | #define PSR_Z_BIT 0x40000000 | ||
| 33 | #define PSR_S_BIT 0x80000000 | ||
| 34 | |||
| 35 | /* | ||
| 36 | * Groups of PSR bits | ||
| 37 | */ | ||
| 38 | #define PSR_f 0xff000000 /* Flags */ | ||
| 39 | #define PSR_c 0x000000ff /* Control */ | ||
| 40 | 16 | ||
| 41 | #ifndef __ASSEMBLY__ | 17 | #ifndef __ASSEMBLY__ |
| 42 | 18 | ||
| 43 | /* | ||
| 44 | * This struct defines the way the registers are stored on the | ||
| 45 | * stack during a system call. Note that sizeof(struct pt_regs) | ||
| 46 | * has to be a multiple of 8. | ||
| 47 | */ | ||
| 48 | struct pt_regs { | ||
| 49 | unsigned long uregs[34]; | ||
| 50 | }; | ||
| 51 | |||
| 52 | #define UCreg_asr uregs[32] | ||
| 53 | #define UCreg_pc uregs[31] | ||
| 54 | #define UCreg_lr uregs[30] | ||
| 55 | #define UCreg_sp uregs[29] | ||
| 56 | #define UCreg_ip uregs[28] | ||
| 57 | #define UCreg_fp uregs[27] | ||
| 58 | #define UCreg_26 uregs[26] | ||
| 59 | #define UCreg_25 uregs[25] | ||
| 60 | #define UCreg_24 uregs[24] | ||
| 61 | #define UCreg_23 uregs[23] | ||
| 62 | #define UCreg_22 uregs[22] | ||
| 63 | #define UCreg_21 uregs[21] | ||
| 64 | #define UCreg_20 uregs[20] | ||
| 65 | #define UCreg_19 uregs[19] | ||
| 66 | #define UCreg_18 uregs[18] | ||
| 67 | #define UCreg_17 uregs[17] | ||
| 68 | #define UCreg_16 uregs[16] | ||
| 69 | #define UCreg_15 uregs[15] | ||
| 70 | #define UCreg_14 uregs[14] | ||
| 71 | #define UCreg_13 uregs[13] | ||
| 72 | #define UCreg_12 uregs[12] | ||
| 73 | #define UCreg_11 uregs[11] | ||
| 74 | #define UCreg_10 uregs[10] | ||
| 75 | #define UCreg_09 uregs[9] | ||
| 76 | #define UCreg_08 uregs[8] | ||
| 77 | #define UCreg_07 uregs[7] | ||
| 78 | #define UCreg_06 uregs[6] | ||
| 79 | #define UCreg_05 uregs[5] | ||
| 80 | #define UCreg_04 uregs[4] | ||
| 81 | #define UCreg_03 uregs[3] | ||
| 82 | #define UCreg_02 uregs[2] | ||
| 83 | #define UCreg_01 uregs[1] | ||
| 84 | #define UCreg_00 uregs[0] | ||
| 85 | #define UCreg_ORIG_00 uregs[33] | ||
| 86 | |||
| 87 | #ifdef __KERNEL__ | ||
| 88 | |||
| 89 | #define user_mode(regs) \ | 19 | #define user_mode(regs) \ |
| 90 | (processor_mode(regs) == USER_MODE) | 20 | (processor_mode(regs) == USER_MODE) |
| 91 | 21 | ||
| @@ -125,9 +55,5 @@ static inline int valid_user_regs(struct pt_regs *regs) | |||
| 125 | 55 | ||
| 126 | #define instruction_pointer(regs) ((regs)->UCreg_pc) | 56 | #define instruction_pointer(regs) ((regs)->UCreg_pc) |
| 127 | 57 | ||
| 128 | #endif /* __KERNEL__ */ | ||
| 129 | |||
| 130 | #endif /* __ASSEMBLY__ */ | 58 | #endif /* __ASSEMBLY__ */ |
| 131 | |||
| 132 | #endif | 59 | #endif |
| 133 | |||
diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild index baebb3da1d44..0514d7ad6855 100644 --- a/arch/unicore32/include/uapi/asm/Kbuild +++ b/arch/unicore32/include/uapi/asm/Kbuild | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | # UAPI Header export list | 1 | # UAPI Header export list |
| 2 | include include/uapi/asm-generic/Kbuild.asm | 2 | include include/uapi/asm-generic/Kbuild.asm |
| 3 | 3 | ||
| 4 | header-y += byteorder.h | ||
| 5 | header-y += kvm_para.h | ||
| 6 | header-y += ptrace.h | ||
| 7 | header-y += sigcontext.h | ||
| 8 | header-y += unistd.h | ||
| 9 | |||
| 10 | generic-y += kvm_para.h | ||
diff --git a/arch/unicore32/include/asm/byteorder.h b/arch/unicore32/include/uapi/asm/byteorder.h index ebe1b3fef3e3..ebe1b3fef3e3 100644 --- a/arch/unicore32/include/asm/byteorder.h +++ b/arch/unicore32/include/uapi/asm/byteorder.h | |||
diff --git a/arch/unicore32/include/uapi/asm/ptrace.h b/arch/unicore32/include/uapi/asm/ptrace.h new file mode 100644 index 000000000000..187aa2e98a53 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/ptrace.h | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/unicore32/include/asm/ptrace.h | ||
| 3 | * | ||
| 4 | * Code specific to PKUnity SoC and UniCore ISA | ||
| 5 | * | ||
| 6 | * Copyright (C) 2001-2010 GUAN Xue-tao | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | #ifndef _UAPI__UNICORE_PTRACE_H__ | ||
| 13 | #define _UAPI__UNICORE_PTRACE_H__ | ||
| 14 | |||
| 15 | #define PTRACE_GET_THREAD_AREA 22 | ||
| 16 | |||
| 17 | /* | ||
| 18 | * PSR bits | ||
| 19 | */ | ||
| 20 | #define USER_MODE 0x00000010 | ||
| 21 | #define REAL_MODE 0x00000011 | ||
| 22 | #define INTR_MODE 0x00000012 | ||
| 23 | #define PRIV_MODE 0x00000013 | ||
| 24 | #define ABRT_MODE 0x00000017 | ||
| 25 | #define EXTN_MODE 0x0000001b | ||
| 26 | #define SUSR_MODE 0x0000001f | ||
| 27 | #define MODE_MASK 0x0000001f | ||
| 28 | #define PSR_R_BIT 0x00000040 | ||
| 29 | #define PSR_I_BIT 0x00000080 | ||
| 30 | #define PSR_V_BIT 0x10000000 | ||
| 31 | #define PSR_C_BIT 0x20000000 | ||
| 32 | #define PSR_Z_BIT 0x40000000 | ||
| 33 | #define PSR_S_BIT 0x80000000 | ||
| 34 | |||
| 35 | /* | ||
| 36 | * Groups of PSR bits | ||
| 37 | */ | ||
| 38 | #define PSR_f 0xff000000 /* Flags */ | ||
| 39 | #define PSR_c 0x000000ff /* Control */ | ||
| 40 | |||
| 41 | #ifndef __ASSEMBLY__ | ||
| 42 | |||
| 43 | /* | ||
| 44 | * This struct defines the way the registers are stored on the | ||
| 45 | * stack during a system call. Note that sizeof(struct pt_regs) | ||
| 46 | * has to be a multiple of 8. | ||
| 47 | */ | ||
| 48 | struct pt_regs { | ||
| 49 | unsigned long uregs[34]; | ||
| 50 | }; | ||
| 51 | |||
| 52 | #define UCreg_asr uregs[32] | ||
| 53 | #define UCreg_pc uregs[31] | ||
| 54 | #define UCreg_lr uregs[30] | ||
| 55 | #define UCreg_sp uregs[29] | ||
| 56 | #define UCreg_ip uregs[28] | ||
| 57 | #define UCreg_fp uregs[27] | ||
| 58 | #define UCreg_26 uregs[26] | ||
| 59 | #define UCreg_25 uregs[25] | ||
| 60 | #define UCreg_24 uregs[24] | ||
| 61 | #define UCreg_23 uregs[23] | ||
| 62 | #define UCreg_22 uregs[22] | ||
| 63 | #define UCreg_21 uregs[21] | ||
| 64 | #define UCreg_20 uregs[20] | ||
| 65 | #define UCreg_19 uregs[19] | ||
| 66 | #define UCreg_18 uregs[18] | ||
| 67 | #define UCreg_17 uregs[17] | ||
| 68 | #define UCreg_16 uregs[16] | ||
| 69 | #define UCreg_15 uregs[15] | ||
| 70 | #define UCreg_14 uregs[14] | ||
| 71 | #define UCreg_13 uregs[13] | ||
| 72 | #define UCreg_12 uregs[12] | ||
| 73 | #define UCreg_11 uregs[11] | ||
| 74 | #define UCreg_10 uregs[10] | ||
| 75 | #define UCreg_09 uregs[9] | ||
| 76 | #define UCreg_08 uregs[8] | ||
| 77 | #define UCreg_07 uregs[7] | ||
| 78 | #define UCreg_06 uregs[6] | ||
| 79 | #define UCreg_05 uregs[5] | ||
| 80 | #define UCreg_04 uregs[4] | ||
| 81 | #define UCreg_03 uregs[3] | ||
| 82 | #define UCreg_02 uregs[2] | ||
| 83 | #define UCreg_01 uregs[1] | ||
| 84 | #define UCreg_00 uregs[0] | ||
| 85 | #define UCreg_ORIG_00 uregs[33] | ||
| 86 | |||
| 87 | |||
| 88 | #endif /* __ASSEMBLY__ */ | ||
| 89 | |||
| 90 | #endif /* _UAPI__UNICORE_PTRACE_H__ */ | ||
diff --git a/arch/unicore32/include/asm/sigcontext.h b/arch/unicore32/include/uapi/asm/sigcontext.h index 6a2d7671c052..6a2d7671c052 100644 --- a/arch/unicore32/include/asm/sigcontext.h +++ b/arch/unicore32/include/uapi/asm/sigcontext.h | |||
diff --git a/arch/unicore32/include/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h index 2abcf61c615d..d18a3be89b38 100644 --- a/arch/unicore32/include/asm/unistd.h +++ b/arch/unicore32/include/uapi/asm/unistd.h | |||
| @@ -12,3 +12,4 @@ | |||
| 12 | 12 | ||
| 13 | /* Use the standard ABI for syscalls. */ | 13 | /* Use the standard ABI for syscalls. */ |
| 14 | #include <asm-generic/unistd.h> | 14 | #include <asm-generic/unistd.h> |
| 15 | #define __ARCH_WANT_SYS_EXECVE | ||
diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index dcb87ab19ddd..7049350c790f 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S | |||
| @@ -573,17 +573,16 @@ ENDPROC(ret_to_user) | |||
| 573 | */ | 573 | */ |
| 574 | ENTRY(ret_from_fork) | 574 | ENTRY(ret_from_fork) |
| 575 | b.l schedule_tail | 575 | b.l schedule_tail |
| 576 | get_thread_info tsk | ||
| 577 | ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing | ||
| 578 | mov why, #1 | ||
| 579 | cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? | ||
| 580 | beq ret_slow_syscall | ||
| 581 | mov r1, sp | ||
| 582 | mov r0, #1 @ trace exit [IP = 1] | ||
| 583 | b.l syscall_trace | ||
| 584 | b ret_slow_syscall | 576 | b ret_slow_syscall |
| 585 | ENDPROC(ret_from_fork) | 577 | ENDPROC(ret_from_fork) |
| 586 | 578 | ||
| 579 | ENTRY(ret_from_kernel_thread) | ||
| 580 | b.l schedule_tail | ||
| 581 | mov r0, r5 | ||
| 582 | adr lr, ret_slow_syscall | ||
| 583 | mov pc, r4 | ||
| 584 | ENDPROC(ret_from_kernel_thread) | ||
| 585 | |||
| 587 | /*============================================================================= | 586 | /*============================================================================= |
| 588 | * SWI handler | 587 | * SWI handler |
| 589 | *----------------------------------------------------------------------------- | 588 | *----------------------------------------------------------------------------- |
| @@ -669,11 +668,6 @@ __cr_alignment: | |||
| 669 | #endif | 668 | #endif |
| 670 | .ltorg | 669 | .ltorg |
| 671 | 670 | ||
| 672 | ENTRY(sys_execve) | ||
| 673 | add r3, sp, #S_OFF | ||
| 674 | b __sys_execve | ||
| 675 | ENDPROC(sys_execve) | ||
| 676 | |||
| 677 | ENTRY(sys_clone) | 671 | ENTRY(sys_clone) |
| 678 | add ip, sp, #S_OFF | 672 | add ip, sp, #S_OFF |
| 679 | stw ip, [sp+], #4 | 673 | stw ip, [sp+], #4 |
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index b008586dad75..a8fe265ce2c0 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c | |||
| @@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task) | |||
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 260 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
| 261 | asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); | ||
| 261 | 262 | ||
| 262 | int | 263 | int |
| 263 | copy_thread(unsigned long clone_flags, unsigned long stack_start, | 264 | copy_thread(unsigned long clone_flags, unsigned long stack_start, |
| @@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, | |||
| 266 | struct thread_info *thread = task_thread_info(p); | 267 | struct thread_info *thread = task_thread_info(p); |
| 267 | struct pt_regs *childregs = task_pt_regs(p); | 268 | struct pt_regs *childregs = task_pt_regs(p); |
| 268 | 269 | ||
| 269 | *childregs = *regs; | ||
| 270 | childregs->UCreg_00 = 0; | ||
| 271 | childregs->UCreg_sp = stack_start; | ||
| 272 | |||
| 273 | memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); | 270 | memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); |
| 274 | thread->cpu_context.sp = (unsigned long)childregs; | 271 | thread->cpu_context.sp = (unsigned long)childregs; |
| 275 | thread->cpu_context.pc = (unsigned long)ret_from_fork; | 272 | if (unlikely(!regs)) { |
| 276 | 273 | thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; | |
| 277 | if (clone_flags & CLONE_SETTLS) | 274 | thread->cpu_context.r4 = stack_start; |
| 278 | childregs->UCreg_16 = regs->UCreg_03; | 275 | thread->cpu_context.r5 = stk_sz; |
| 276 | memset(childregs, 0, sizeof(struct pt_regs)); | ||
| 277 | } else { | ||
| 278 | thread->cpu_context.pc = (unsigned long)ret_from_fork; | ||
| 279 | *childregs = *regs; | ||
| 280 | childregs->UCreg_00 = 0; | ||
| 281 | childregs->UCreg_sp = stack_start; | ||
| 279 | 282 | ||
| 283 | if (clone_flags & CLONE_SETTLS) | ||
| 284 | childregs->UCreg_16 = regs->UCreg_03; | ||
| 285 | } | ||
| 280 | return 0; | 286 | return 0; |
| 281 | } | 287 | } |
| 282 | 288 | ||
| @@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) | |||
| 305 | } | 311 | } |
| 306 | EXPORT_SYMBOL(dump_fpu); | 312 | EXPORT_SYMBOL(dump_fpu); |
| 307 | 313 | ||
| 308 | /* | ||
| 309 | * Shuffle the argument into the correct register before calling the | ||
| 310 | * thread function. r1 is the thread argument, r2 is the pointer to | ||
| 311 | * the thread function, and r3 points to the exit function. | ||
| 312 | */ | ||
| 313 | asm(".pushsection .text\n" | ||
| 314 | " .align\n" | ||
| 315 | " .type kernel_thread_helper, #function\n" | ||
| 316 | "kernel_thread_helper:\n" | ||
| 317 | " mov.a asr, r7\n" | ||
| 318 | " mov r0, r4\n" | ||
| 319 | " mov lr, r6\n" | ||
| 320 | " mov pc, r5\n" | ||
| 321 | " .size kernel_thread_helper, . - kernel_thread_helper\n" | ||
| 322 | " .popsection"); | ||
| 323 | |||
| 324 | /* | ||
| 325 | * Create a kernel thread. | ||
| 326 | */ | ||
| 327 | pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
| 328 | { | ||
| 329 | struct pt_regs regs; | ||
| 330 | |||
| 331 | memset(®s, 0, sizeof(regs)); | ||
| 332 | |||
| 333 | regs.UCreg_04 = (unsigned long)arg; | ||
| 334 | regs.UCreg_05 = (unsigned long)fn; | ||
| 335 | regs.UCreg_06 = (unsigned long)do_exit; | ||
| 336 | regs.UCreg_07 = PRIV_MODE; | ||
| 337 | regs.UCreg_pc = (unsigned long)kernel_thread_helper; | ||
| 338 | regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; | ||
| 339 | |||
| 340 | return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | ||
| 341 | } | ||
| 342 | EXPORT_SYMBOL(kernel_thread); | ||
| 343 | |||
| 344 | unsigned long get_wchan(struct task_struct *p) | 314 | unsigned long get_wchan(struct task_struct *p) |
| 345 | { | 315 | { |
| 346 | struct stackframe frame; | 316 | struct stackframe frame; |
diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h index f23955028a18..30f749da8f73 100644 --- a/arch/unicore32/kernel/setup.h +++ b/arch/unicore32/kernel/setup.h | |||
| @@ -30,4 +30,10 @@ extern char __vectors_start[], __vectors_end[]; | |||
| 30 | extern void kernel_thread_helper(void); | 30 | extern void kernel_thread_helper(void); |
| 31 | 31 | ||
| 32 | extern void __init early_signal_init(void); | 32 | extern void __init early_signal_init(void); |
| 33 | |||
| 34 | extern asmlinkage void __backtrace(void); | ||
| 35 | extern asmlinkage void c_backtrace(unsigned long fp, int pmode); | ||
| 36 | |||
| 37 | extern void __show_regs(struct pt_regs *); | ||
| 38 | |||
| 33 | #endif | 39 | #endif |
diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index fabdee96110b..9680134b31f0 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c | |||
| @@ -42,69 +42,6 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
| 42 | parent_tid, child_tid); | 42 | parent_tid, child_tid); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | /* sys_execve() executes a new program. | ||
| 46 | * This is called indirectly via a small wrapper | ||
| 47 | */ | ||
| 48 | asmlinkage long __sys_execve(const char __user *filename, | ||
| 49 | const char __user *const __user *argv, | ||
| 50 | const char __user *const __user *envp, | ||
| 51 | struct pt_regs *regs) | ||
| 52 | { | ||
| 53 | int error; | ||
| 54 | struct filename *fn; | ||
| 55 | |||
| 56 | fn = getname(filename); | ||
| 57 | error = PTR_ERR(fn); | ||
| 58 | if (IS_ERR(fn)) | ||
| 59 | goto out; | ||
| 60 | error = do_execve(fn->name, argv, envp, regs); | ||
| 61 | putname(fn); | ||
| 62 | out: | ||
| 63 | return error; | ||
| 64 | } | ||
| 65 | |||
| 66 | int kernel_execve(const char *filename, | ||
| 67 | const char *const argv[], | ||
| 68 | const char *const envp[]) | ||
| 69 | { | ||
| 70 | struct pt_regs regs; | ||
| 71 | int ret; | ||
| 72 | |||
| 73 | memset(®s, 0, sizeof(struct pt_regs)); | ||
| 74 | ret = do_execve(filename, | ||
| 75 | (const char __user *const __user *)argv, | ||
| 76 | (const char __user *const __user *)envp, ®s); | ||
| 77 | if (ret < 0) | ||
| 78 | goto out; | ||
| 79 | |||
| 80 | /* | ||
| 81 | * Save argc to the register structure for userspace. | ||
| 82 | */ | ||
| 83 | regs.UCreg_00 = ret; | ||
| 84 | |||
| 85 | /* | ||
| 86 | * We were successful. We won't be returning to our caller, but | ||
| 87 | * instead to user space by manipulating the kernel stack. | ||
| 88 | */ | ||
| 89 | asm("add r0, %0, %1\n\t" | ||
| 90 | "mov r1, %2\n\t" | ||
| 91 | "mov r2, %3\n\t" | ||
| 92 | "mov r22, #0\n\t" /* not a syscall */ | ||
| 93 | "mov r23, %0\n\t" /* thread structure */ | ||
| 94 | "b.l memmove\n\t" /* copy regs to top of stack */ | ||
| 95 | "mov sp, r0\n\t" /* reposition stack pointer */ | ||
| 96 | "b ret_to_user" | ||
| 97 | : | ||
| 98 | : "r" (current_thread_info()), | ||
| 99 | "Ir" (THREAD_START_SP - sizeof(regs)), | ||
| 100 | "r" (®s), | ||
| 101 | "Ir" (sizeof(regs)) | ||
| 102 | : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); | ||
| 103 | |||
| 104 | out: | ||
| 105 | return ret; | ||
| 106 | } | ||
| 107 | |||
| 108 | /* Note: used by the compat code even in 64-bit Linux. */ | 45 | /* Note: used by the compat code even in 64-bit Linux. */ |
| 109 | SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, | 46 | SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, |
| 110 | unsigned long, prot, unsigned long, flags, | 47 | unsigned long, prot, unsigned long, flags, |
diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c index 2eeb9c04cab0..f9b5c10bccee 100644 --- a/arch/unicore32/mm/fault.c +++ b/arch/unicore32/mm/fault.c | |||
| @@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) | |||
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr, | 170 | static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr, |
| 171 | struct task_struct *tsk) | 171 | unsigned int flags, struct task_struct *tsk) |
| 172 | { | 172 | { |
| 173 | struct vm_area_struct *vma; | 173 | struct vm_area_struct *vma; |
| 174 | int fault; | 174 | int fault; |
| @@ -194,14 +194,7 @@ good_area: | |||
| 194 | * If for any reason at all we couldn't handle the fault, make | 194 | * If for any reason at all we couldn't handle the fault, make |
| 195 | * sure we exit gracefully rather than endlessly redo the fault. | 195 | * sure we exit gracefully rather than endlessly redo the fault. |
| 196 | */ | 196 | */ |
| 197 | fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, | 197 | fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); |
| 198 | (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); | ||
| 199 | if (unlikely(fault & VM_FAULT_ERROR)) | ||
| 200 | return fault; | ||
| 201 | if (fault & VM_FAULT_MAJOR) | ||
| 202 | tsk->maj_flt++; | ||
| 203 | else | ||
| 204 | tsk->min_flt++; | ||
| 205 | return fault; | 198 | return fault; |
| 206 | 199 | ||
| 207 | check_stack: | 200 | check_stack: |
| @@ -216,6 +209,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
| 216 | struct task_struct *tsk; | 209 | struct task_struct *tsk; |
| 217 | struct mm_struct *mm; | 210 | struct mm_struct *mm; |
| 218 | int fault, sig, code; | 211 | int fault, sig, code; |
| 212 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | | ||
| 213 | ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); | ||
| 219 | 214 | ||
| 220 | tsk = current; | 215 | tsk = current; |
| 221 | mm = tsk->mm; | 216 | mm = tsk->mm; |
| @@ -236,6 +231,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
| 236 | if (!user_mode(regs) | 231 | if (!user_mode(regs) |
| 237 | && !search_exception_tables(regs->UCreg_pc)) | 232 | && !search_exception_tables(regs->UCreg_pc)) |
| 238 | goto no_context; | 233 | goto no_context; |
| 234 | retry: | ||
| 239 | down_read(&mm->mmap_sem); | 235 | down_read(&mm->mmap_sem); |
| 240 | } else { | 236 | } else { |
| 241 | /* | 237 | /* |
| @@ -251,7 +247,28 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
| 251 | #endif | 247 | #endif |
| 252 | } | 248 | } |
| 253 | 249 | ||
| 254 | fault = __do_pf(mm, addr, fsr, tsk); | 250 | fault = __do_pf(mm, addr, fsr, flags, tsk); |
| 251 | |||
| 252 | /* If we need to retry but a fatal signal is pending, handle the | ||
| 253 | * signal first. We do not need to release the mmap_sem because | ||
| 254 | * it would already be released in __lock_page_or_retry in | ||
| 255 | * mm/filemap.c. */ | ||
| 256 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | ||
| 257 | return 0; | ||
| 258 | |||
| 259 | if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) { | ||
| 260 | if (fault & VM_FAULT_MAJOR) | ||
| 261 | tsk->maj_flt++; | ||
| 262 | else | ||
| 263 | tsk->min_flt++; | ||
| 264 | if (fault & VM_FAULT_RETRY) { | ||
| 265 | /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk | ||
| 266 | * of starvation. */ | ||
| 267 | flags &= ~FAULT_FLAG_ALLOW_RETRY; | ||
| 268 | goto retry; | ||
| 269 | } | ||
| 270 | } | ||
| 271 | |||
| 255 | up_read(&mm->mmap_sem); | 272 | up_read(&mm->mmap_sem); |
| 256 | 273 | ||
| 257 | /* | 274 | /* |
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index 59c226d120cd..c20d1ce62dc6 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h | |||
| @@ -359,18 +359,14 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val, | |||
| 359 | return _hypercall4(int, update_va_mapping, va, | 359 | return _hypercall4(int, update_va_mapping, va, |
| 360 | new_val.pte, new_val.pte >> 32, flags); | 360 | new_val.pte, new_val.pte >> 32, flags); |
| 361 | } | 361 | } |
| 362 | extern int __must_check xen_event_channel_op_compat(int, void *); | ||
| 362 | 363 | ||
| 363 | static inline int | 364 | static inline int |
| 364 | HYPERVISOR_event_channel_op(int cmd, void *arg) | 365 | HYPERVISOR_event_channel_op(int cmd, void *arg) |
| 365 | { | 366 | { |
| 366 | int rc = _hypercall2(int, event_channel_op, cmd, arg); | 367 | int rc = _hypercall2(int, event_channel_op, cmd, arg); |
| 367 | if (unlikely(rc == -ENOSYS)) { | 368 | if (unlikely(rc == -ENOSYS)) |
| 368 | struct evtchn_op op; | 369 | rc = xen_event_channel_op_compat(cmd, arg); |
| 369 | op.cmd = cmd; | ||
| 370 | memcpy(&op.u, arg, sizeof(op.u)); | ||
| 371 | rc = _hypercall1(int, event_channel_op_compat, &op); | ||
| 372 | memcpy(arg, &op.u, sizeof(op.u)); | ||
| 373 | } | ||
| 374 | return rc; | 370 | return rc; |
| 375 | } | 371 | } |
| 376 | 372 | ||
| @@ -386,17 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str) | |||
| 386 | return _hypercall3(int, console_io, cmd, count, str); | 382 | return _hypercall3(int, console_io, cmd, count, str); |
| 387 | } | 383 | } |
| 388 | 384 | ||
| 385 | extern int __must_check HYPERVISOR_physdev_op_compat(int, void *); | ||
| 386 | |||
| 389 | static inline int | 387 | static inline int |
| 390 | HYPERVISOR_physdev_op(int cmd, void *arg) | 388 | HYPERVISOR_physdev_op(int cmd, void *arg) |
| 391 | { | 389 | { |
| 392 | int rc = _hypercall2(int, physdev_op, cmd, arg); | 390 | int rc = _hypercall2(int, physdev_op, cmd, arg); |
| 393 | if (unlikely(rc == -ENOSYS)) { | 391 | if (unlikely(rc == -ENOSYS)) |
| 394 | struct physdev_op op; | 392 | rc = HYPERVISOR_physdev_op_compat(cmd, arg); |
| 395 | op.cmd = cmd; | ||
| 396 | memcpy(&op.u, arg, sizeof(op.u)); | ||
| 397 | rc = _hypercall1(int, physdev_op_compat, &op); | ||
| 398 | memcpy(arg, &op.u, sizeof(op.u)); | ||
| 399 | } | ||
| 400 | return rc; | 393 | return rc; |
| 401 | } | 394 | } |
| 402 | 395 | ||
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index a10e46016851..58fc51488828 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h | |||
| @@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) | |||
| 24 | { | 24 | { |
| 25 | struct kvm_cpuid_entry2 *best; | 25 | struct kvm_cpuid_entry2 *best; |
| 26 | 26 | ||
| 27 | if (!static_cpu_has(X86_FEATURE_XSAVE)) | ||
| 28 | return 0; | ||
| 29 | |||
| 27 | best = kvm_find_cpuid_entry(vcpu, 1, 0); | 30 | best = kvm_find_cpuid_entry(vcpu, 1, 0); |
| 28 | return best && (best->ecx & bit(X86_FEATURE_XSAVE)); | 31 | return best && (best->ecx & bit(X86_FEATURE_XSAVE)); |
| 29 | } | 32 | } |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 224a7e78cb6c..4f7641756be2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -5781,6 +5781,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
| 5781 | int pending_vec, max_bits, idx; | 5781 | int pending_vec, max_bits, idx; |
| 5782 | struct desc_ptr dt; | 5782 | struct desc_ptr dt; |
| 5783 | 5783 | ||
| 5784 | if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE)) | ||
| 5785 | return -EINVAL; | ||
| 5786 | |||
| 5784 | dt.size = sregs->idt.limit; | 5787 | dt.size = sregs->idt.limit; |
| 5785 | dt.address = sregs->idt.base; | 5788 | dt.address = sregs->idt.base; |
| 5786 | kvm_x86_ops->set_idt(vcpu, &dt); | 5789 | kvm_x86_ops->set_idt(vcpu, &dt); |
diff --git a/crypto/cryptd.c b/crypto/cryptd.c index 671d4d6d14df..7bdd61b867c8 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c | |||
| @@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct work_struct *work) | |||
| 137 | struct crypto_async_request *req, *backlog; | 137 | struct crypto_async_request *req, *backlog; |
| 138 | 138 | ||
| 139 | cpu_queue = container_of(work, struct cryptd_cpu_queue, work); | 139 | cpu_queue = container_of(work, struct cryptd_cpu_queue, work); |
| 140 | /* Only handle one request at a time to avoid hogging crypto | 140 | /* |
| 141 | * workqueue. preempt_disable/enable is used to prevent | 141 | * Only handle one request at a time to avoid hogging crypto workqueue. |
| 142 | * being preempted by cryptd_enqueue_request() */ | 142 | * preempt_disable/enable is used to prevent being preempted by |
| 143 | * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent | ||
| 144 | * cryptd_enqueue_request() being accessed from software interrupts. | ||
| 145 | */ | ||
| 146 | local_bh_disable(); | ||
| 143 | preempt_disable(); | 147 | preempt_disable(); |
| 144 | backlog = crypto_get_backlog(&cpu_queue->queue); | 148 | backlog = crypto_get_backlog(&cpu_queue->queue); |
| 145 | req = crypto_dequeue_request(&cpu_queue->queue); | 149 | req = crypto_dequeue_request(&cpu_queue->queue); |
| 146 | preempt_enable(); | 150 | preempt_enable(); |
| 151 | local_bh_enable(); | ||
| 147 | 152 | ||
| 148 | if (!req) | 153 | if (!req) |
| 149 | return; | 154 | return; |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 8727e9c5eea4..72c776f2a1f5 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
| @@ -83,9 +83,16 @@ EXPORT_SYMBOL_GPL(platform_get_resource); | |||
| 83 | */ | 83 | */ |
| 84 | int platform_get_irq(struct platform_device *dev, unsigned int num) | 84 | int platform_get_irq(struct platform_device *dev, unsigned int num) |
| 85 | { | 85 | { |
| 86 | #ifdef CONFIG_SPARC | ||
| 87 | /* sparc does not have irqs represented as IORESOURCE_IRQ resources */ | ||
| 88 | if (!dev || num >= dev->archdata.num_irqs) | ||
| 89 | return -ENXIO; | ||
| 90 | return dev->archdata.irqs[num]; | ||
| 91 | #else | ||
| 86 | struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); | 92 | struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); |
| 87 | 93 | ||
| 88 | return r ? r->start : -ENXIO; | 94 | return r ? r->start : -ENXIO; |
| 95 | #endif | ||
| 89 | } | 96 | } |
| 90 | EXPORT_SYMBOL_GPL(platform_get_irq); | 97 | EXPORT_SYMBOL_GPL(platform_get_irq); |
| 91 | 98 | ||
diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index ca4a25ed844c..e2c17d187d98 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c | |||
| @@ -40,7 +40,7 @@ void u8500_clk_init(void) | |||
| 40 | CLK_IS_ROOT|CLK_IGNORE_UNUSED, | 40 | CLK_IS_ROOT|CLK_IGNORE_UNUSED, |
| 41 | 32768); | 41 | 32768); |
| 42 | clk_register_clkdev(clk, "clk32k", NULL); | 42 | clk_register_clkdev(clk, "clk32k", NULL); |
| 43 | clk_register_clkdev(clk, NULL, "rtc-pl031"); | 43 | clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); |
| 44 | 44 | ||
| 45 | /* PRCMU clocks */ | 45 | /* PRCMU clocks */ |
| 46 | fw_version = prcmu_get_fw_version(); | 46 | fw_version = prcmu_get_fw_version(); |
| @@ -228,10 +228,17 @@ void u8500_clk_init(void) | |||
| 228 | 228 | ||
| 229 | clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, | 229 | clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, |
| 230 | BIT(2), 0); | 230 | BIT(2), 0); |
| 231 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); | ||
| 232 | |||
| 231 | clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, | 233 | clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, |
| 232 | BIT(3), 0); | 234 | BIT(3), 0); |
| 235 | clk_register_clkdev(clk, "apb_pclk", "msp0"); | ||
| 236 | clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0"); | ||
| 237 | |||
| 233 | clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, | 238 | clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, |
| 234 | BIT(4), 0); | 239 | BIT(4), 0); |
| 240 | clk_register_clkdev(clk, "apb_pclk", "msp1"); | ||
| 241 | clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1"); | ||
| 235 | 242 | ||
| 236 | clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, | 243 | clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, |
| 237 | BIT(5), 0); | 244 | BIT(5), 0); |
| @@ -239,6 +246,7 @@ void u8500_clk_init(void) | |||
| 239 | 246 | ||
| 240 | clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, | 247 | clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, |
| 241 | BIT(6), 0); | 248 | BIT(6), 0); |
| 249 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); | ||
| 242 | 250 | ||
| 243 | clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, | 251 | clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, |
| 244 | BIT(7), 0); | 252 | BIT(7), 0); |
| @@ -246,6 +254,7 @@ void u8500_clk_init(void) | |||
| 246 | 254 | ||
| 247 | clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, | 255 | clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, |
| 248 | BIT(8), 0); | 256 | BIT(8), 0); |
| 257 | clk_register_clkdev(clk, "apb_pclk", "slimbus0"); | ||
| 249 | 258 | ||
| 250 | clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, | 259 | clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, |
| 251 | BIT(9), 0); | 260 | BIT(9), 0); |
| @@ -255,11 +264,16 @@ void u8500_clk_init(void) | |||
| 255 | 264 | ||
| 256 | clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, | 265 | clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, |
| 257 | BIT(10), 0); | 266 | BIT(10), 0); |
| 267 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); | ||
| 268 | |||
| 258 | clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, | 269 | clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, |
| 259 | BIT(11), 0); | 270 | BIT(11), 0); |
| 271 | clk_register_clkdev(clk, "apb_pclk", "msp3"); | ||
| 272 | clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3"); | ||
| 260 | 273 | ||
| 261 | clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, | 274 | clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, |
| 262 | BIT(0), 0); | 275 | BIT(0), 0); |
| 276 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); | ||
| 263 | 277 | ||
| 264 | clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, | 278 | clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, |
| 265 | BIT(1), 0); | 279 | BIT(1), 0); |
| @@ -279,12 +293,13 @@ void u8500_clk_init(void) | |||
| 279 | 293 | ||
| 280 | clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, | 294 | clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, |
| 281 | BIT(5), 0); | 295 | BIT(5), 0); |
| 296 | clk_register_clkdev(clk, "apb_pclk", "msp2"); | ||
| 297 | clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2"); | ||
| 282 | 298 | ||
| 283 | clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, | 299 | clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, |
| 284 | BIT(6), 0); | 300 | BIT(6), 0); |
| 285 | clk_register_clkdev(clk, "apb_pclk", "sdi1"); | 301 | clk_register_clkdev(clk, "apb_pclk", "sdi1"); |
| 286 | 302 | ||
| 287 | |||
| 288 | clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, | 303 | clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, |
| 289 | BIT(7), 0); | 304 | BIT(7), 0); |
| 290 | clk_register_clkdev(clk, "apb_pclk", "sdi3"); | 305 | clk_register_clkdev(clk, "apb_pclk", "sdi3"); |
| @@ -316,10 +331,15 @@ void u8500_clk_init(void) | |||
| 316 | 331 | ||
| 317 | clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, | 332 | clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, |
| 318 | BIT(1), 0); | 333 | BIT(1), 0); |
| 334 | clk_register_clkdev(clk, "apb_pclk", "ssp0"); | ||
| 335 | |||
| 319 | clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, | 336 | clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, |
| 320 | BIT(2), 0); | 337 | BIT(2), 0); |
| 338 | clk_register_clkdev(clk, "apb_pclk", "ssp1"); | ||
| 339 | |||
| 321 | clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, | 340 | clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, |
| 322 | BIT(3), 0); | 341 | BIT(3), 0); |
| 342 | clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); | ||
| 323 | 343 | ||
| 324 | clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, | 344 | clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, |
| 325 | BIT(4), 0); | 345 | BIT(4), 0); |
| @@ -401,10 +421,17 @@ void u8500_clk_init(void) | |||
| 401 | 421 | ||
| 402 | clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", | 422 | clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", |
| 403 | U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); | 423 | U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); |
| 424 | clk_register_clkdev(clk, NULL, "nmk-i2c.1"); | ||
| 425 | |||
| 404 | clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", | 426 | clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", |
| 405 | U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); | 427 | U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 428 | clk_register_clkdev(clk, NULL, "msp0"); | ||
| 429 | clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0"); | ||
| 430 | |||
| 406 | clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", | 431 | clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", |
| 407 | U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); | 432 | U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); |
| 433 | clk_register_clkdev(clk, NULL, "msp1"); | ||
| 434 | clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1"); | ||
| 408 | 435 | ||
| 409 | clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", | 436 | clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", |
| 410 | U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); | 437 | U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); |
| @@ -412,17 +439,25 @@ void u8500_clk_init(void) | |||
| 412 | 439 | ||
| 413 | clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", | 440 | clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", |
| 414 | U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); | 441 | U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); |
| 442 | clk_register_clkdev(clk, NULL, "nmk-i2c.2"); | ||
| 443 | |||
| 415 | clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", | 444 | clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", |
| 416 | U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); | 445 | U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE); |
| 417 | /* FIXME: Redefinition of BIT(3). */ | 446 | clk_register_clkdev(clk, NULL, "slimbus0"); |
| 447 | |||
| 418 | clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", | 448 | clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", |
| 419 | U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); | 449 | U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); |
| 450 | clk_register_clkdev(clk, NULL, "nmk-i2c.4"); | ||
| 451 | |||
| 420 | clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", | 452 | clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", |
| 421 | U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); | 453 | U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); |
| 454 | clk_register_clkdev(clk, NULL, "msp3"); | ||
| 455 | clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3"); | ||
| 422 | 456 | ||
| 423 | /* Periph2 */ | 457 | /* Periph2 */ |
| 424 | clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", | 458 | clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", |
| 425 | U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); | 459 | U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); |
| 460 | clk_register_clkdev(clk, NULL, "nmk-i2c.3"); | ||
| 426 | 461 | ||
| 427 | clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", | 462 | clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", |
| 428 | U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); | 463 | U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); |
| @@ -430,6 +465,8 @@ void u8500_clk_init(void) | |||
| 430 | 465 | ||
| 431 | clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", | 466 | clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", |
| 432 | U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); | 467 | U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 468 | clk_register_clkdev(clk, NULL, "msp2"); | ||
| 469 | clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2"); | ||
| 433 | 470 | ||
| 434 | clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", | 471 | clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", |
| 435 | U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); | 472 | U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); |
| @@ -450,10 +487,15 @@ void u8500_clk_init(void) | |||
| 450 | /* Periph3 */ | 487 | /* Periph3 */ |
| 451 | clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", | 488 | clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", |
| 452 | U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); | 489 | U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); |
| 490 | clk_register_clkdev(clk, NULL, "ssp0"); | ||
| 491 | |||
| 453 | clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", | 492 | clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", |
| 454 | U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); | 493 | U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); |
| 494 | clk_register_clkdev(clk, NULL, "ssp1"); | ||
| 495 | |||
| 455 | clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", | 496 | clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", |
| 456 | U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); | 497 | U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 498 | clk_register_clkdev(clk, NULL, "nmk-i2c.0"); | ||
| 457 | 499 | ||
| 458 | clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", | 500 | clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", |
| 459 | U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); | 501 | U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d055cee36942..f11d8e3b4041 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
| @@ -47,7 +47,7 @@ if GPIOLIB | |||
| 47 | 47 | ||
| 48 | config OF_GPIO | 48 | config OF_GPIO |
| 49 | def_bool y | 49 | def_bool y |
| 50 | depends on OF && !SPARC | 50 | depends on OF |
| 51 | 51 | ||
| 52 | config DEBUG_GPIO | 52 | config DEBUG_GPIO |
| 53 | bool "Debug GPIO calls" | 53 | bool "Debug GPIO calls" |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index b726b478a4f5..6345878ae1e7 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -143,7 +143,7 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode) | |||
| 143 | int old_dpms; | 143 | int old_dpms; |
| 144 | 144 | ||
| 145 | /* PCH platforms and VLV only support on/off. */ | 145 | /* PCH platforms and VLV only support on/off. */ |
| 146 | if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON) | 146 | if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON) |
| 147 | mode = DRM_MODE_DPMS_OFF; | 147 | mode = DRM_MODE_DPMS_OFF; |
| 148 | 148 | ||
| 149 | if (mode == connector->dpms) | 149 | if (mode == connector->dpms) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 461a637f1ef7..4154bcd7a070 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -3841,6 +3841,17 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
| 3841 | } | 3841 | } |
| 3842 | } | 3842 | } |
| 3843 | 3843 | ||
| 3844 | if (intel_encoder->type == INTEL_OUTPUT_EDP) { | ||
| 3845 | /* Use VBT settings if we have an eDP panel */ | ||
| 3846 | unsigned int edp_bpc = dev_priv->edp.bpp / 3; | ||
| 3847 | |||
| 3848 | if (edp_bpc < display_bpc) { | ||
| 3849 | DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); | ||
| 3850 | display_bpc = edp_bpc; | ||
| 3851 | } | ||
| 3852 | continue; | ||
| 3853 | } | ||
| 3854 | |||
| 3844 | /* | 3855 | /* |
| 3845 | * HDMI is either 12 or 8, so if the display lets 10bpc sneak | 3856 | * HDMI is either 12 or 8, so if the display lets 10bpc sneak |
| 3846 | * through, clamp it down. (Note: >12bpc will be caught below.) | 3857 | * through, clamp it down. (Note: >12bpc will be caught below.) |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 79d308da29ff..c600fb06e25e 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -2382,6 +2382,18 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) | |||
| 2382 | return true; | 2382 | return true; |
| 2383 | } | 2383 | } |
| 2384 | 2384 | ||
| 2385 | static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo) | ||
| 2386 | { | ||
| 2387 | struct drm_device *dev = intel_sdvo->base.base.dev; | ||
| 2388 | struct drm_connector *connector, *tmp; | ||
| 2389 | |||
| 2390 | list_for_each_entry_safe(connector, tmp, | ||
| 2391 | &dev->mode_config.connector_list, head) { | ||
| 2392 | if (intel_attached_encoder(connector) == &intel_sdvo->base) | ||
| 2393 | intel_sdvo_destroy(connector); | ||
| 2394 | } | ||
| 2395 | } | ||
| 2396 | |||
| 2385 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, | 2397 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
| 2386 | struct intel_sdvo_connector *intel_sdvo_connector, | 2398 | struct intel_sdvo_connector *intel_sdvo_connector, |
| 2387 | int type) | 2399 | int type) |
| @@ -2705,7 +2717,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
| 2705 | intel_sdvo->caps.output_flags) != true) { | 2717 | intel_sdvo->caps.output_flags) != true) { |
| 2706 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", | 2718 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", |
| 2707 | SDVO_NAME(intel_sdvo)); | 2719 | SDVO_NAME(intel_sdvo)); |
| 2708 | goto err; | 2720 | /* Output_setup can leave behind connectors! */ |
| 2721 | goto err_output; | ||
| 2709 | } | 2722 | } |
| 2710 | 2723 | ||
| 2711 | /* Only enable the hotplug irq if we need it, to work around noisy | 2724 | /* Only enable the hotplug irq if we need it, to work around noisy |
| @@ -2718,12 +2731,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
| 2718 | 2731 | ||
| 2719 | /* Set the input timing to the screen. Assume always input 0. */ | 2732 | /* Set the input timing to the screen. Assume always input 0. */ |
| 2720 | if (!intel_sdvo_set_target_input(intel_sdvo)) | 2733 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| 2721 | goto err; | 2734 | goto err_output; |
| 2722 | 2735 | ||
| 2723 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, | 2736 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, |
| 2724 | &intel_sdvo->pixel_clock_min, | 2737 | &intel_sdvo->pixel_clock_min, |
| 2725 | &intel_sdvo->pixel_clock_max)) | 2738 | &intel_sdvo->pixel_clock_max)) |
| 2726 | goto err; | 2739 | goto err_output; |
| 2727 | 2740 | ||
| 2728 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " | 2741 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " |
| 2729 | "clock range %dMHz - %dMHz, " | 2742 | "clock range %dMHz - %dMHz, " |
| @@ -2743,6 +2756,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
| 2743 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); | 2756 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
| 2744 | return true; | 2757 | return true; |
| 2745 | 2758 | ||
| 2759 | err_output: | ||
| 2760 | intel_sdvo_output_cleanup(intel_sdvo); | ||
| 2761 | |||
| 2746 | err: | 2762 | err: |
| 2747 | drm_encoder_cleanup(&intel_encoder->base); | 2763 | drm_encoder_cleanup(&intel_encoder->base); |
| 2748 | i2c_del_adapter(&intel_sdvo->ddc); | 2764 | i2c_del_adapter(&intel_sdvo->ddc); |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index ba498f8e47a2..010bae19554a 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
| @@ -1625,7 +1625,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
| 1625 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | 1625 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); |
| 1626 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1626 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
| 1627 | /* some early dce3.2 boards have a bug in their transmitter control table */ | 1627 | /* some early dce3.2 boards have a bug in their transmitter control table */ |
| 1628 | if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) | 1628 | if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730)) |
| 1629 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | 1629 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
| 1630 | } | 1630 | } |
| 1631 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1631 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 860dc4813e99..bd2a3b40cd12 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | |||
| @@ -749,7 +749,10 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, | |||
| 749 | /* clear the pages coming from the pool if requested */ | 749 | /* clear the pages coming from the pool if requested */ |
| 750 | if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) { | 750 | if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) { |
| 751 | list_for_each_entry(p, &plist, lru) { | 751 | list_for_each_entry(p, &plist, lru) { |
| 752 | clear_page(page_address(p)); | 752 | if (PageHighMem(p)) |
| 753 | clear_highpage(p); | ||
| 754 | else | ||
| 755 | clear_page(page_address(p)); | ||
| 753 | } | 756 | } |
| 754 | } | 757 | } |
| 755 | 758 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index bf8260133ea9..7d759a430294 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
| @@ -308,9 +308,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm) | |||
| 308 | if (unlikely(to_page == NULL)) | 308 | if (unlikely(to_page == NULL)) |
| 309 | goto out_err; | 309 | goto out_err; |
| 310 | 310 | ||
| 311 | preempt_disable(); | ||
| 312 | copy_highpage(to_page, from_page); | 311 | copy_highpage(to_page, from_page); |
| 313 | preempt_enable(); | ||
| 314 | page_cache_release(from_page); | 312 | page_cache_release(from_page); |
| 315 | } | 313 | } |
| 316 | 314 | ||
| @@ -358,9 +356,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage) | |||
| 358 | ret = PTR_ERR(to_page); | 356 | ret = PTR_ERR(to_page); |
| 359 | goto out_err; | 357 | goto out_err; |
| 360 | } | 358 | } |
| 361 | preempt_disable(); | ||
| 362 | copy_highpage(to_page, from_page); | 359 | copy_highpage(to_page, from_page); |
| 363 | preempt_enable(); | ||
| 364 | set_page_dirty(to_page); | 360 | set_page_dirty(to_page); |
| 365 | mark_page_accessed(to_page); | 361 | mark_page_accessed(to_page); |
| 366 | page_cache_release(to_page); | 362 | page_cache_release(to_page); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c index 3ce68a2e312d..d1498bfd7873 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c | |||
| @@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin) | |||
| 306 | 306 | ||
| 307 | BUG_ON(!atomic_read(&bo->reserved)); | 307 | BUG_ON(!atomic_read(&bo->reserved)); |
| 308 | BUG_ON(old_mem_type != TTM_PL_VRAM && | 308 | BUG_ON(old_mem_type != TTM_PL_VRAM && |
| 309 | old_mem_type != VMW_PL_FLAG_GMR); | 309 | old_mem_type != VMW_PL_GMR); |
| 310 | 310 | ||
| 311 | pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; | 311 | pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; |
| 312 | if (pin) | 312 | if (pin) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index ed3c1e7ddde9..2dd185e42f21 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
| @@ -1098,6 +1098,11 @@ static void vmw_pm_complete(struct device *kdev) | |||
| 1098 | struct drm_device *dev = pci_get_drvdata(pdev); | 1098 | struct drm_device *dev = pci_get_drvdata(pdev); |
| 1099 | struct vmw_private *dev_priv = vmw_priv(dev); | 1099 | struct vmw_private *dev_priv = vmw_priv(dev); |
| 1100 | 1100 | ||
| 1101 | mutex_lock(&dev_priv->hw_mutex); | ||
| 1102 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | ||
| 1103 | (void) vmw_read(dev_priv, SVGA_REG_ID); | ||
| 1104 | mutex_unlock(&dev_priv->hw_mutex); | ||
| 1105 | |||
| 1101 | /** | 1106 | /** |
| 1102 | * Reclaim 3d reference held by fbdev and potentially | 1107 | * Reclaim 3d reference held by fbdev and potentially |
| 1103 | * start fifo. | 1108 | * start fifo. |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index b07ca2e4d04b..7290811f89be 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
| @@ -110,6 +110,8 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | |||
| 110 | memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); | 110 | memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); |
| 111 | 111 | ||
| 112 | ret = copy_to_user(buffer, bounce, size); | 112 | ret = copy_to_user(buffer, bounce, size); |
| 113 | if (ret) | ||
| 114 | ret = -EFAULT; | ||
| 113 | vfree(bounce); | 115 | vfree(bounce); |
| 114 | 116 | ||
| 115 | if (unlikely(ret != 0)) | 117 | if (unlikely(ret != 0)) |
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 1630150ad2b1..e7d6a13ec6a6 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
| @@ -265,6 +265,15 @@ config HID_GYRATION | |||
| 265 | ---help--- | 265 | ---help--- |
| 266 | Support for Gyration remote control. | 266 | Support for Gyration remote control. |
| 267 | 267 | ||
| 268 | config HID_ICADE | ||
| 269 | tristate "ION iCade arcade controller" | ||
| 270 | depends on BT_HIDP | ||
| 271 | ---help--- | ||
| 272 | Support for the ION iCade arcade controller to work as a joystick. | ||
| 273 | |||
| 274 | To compile this driver as a module, choose M here: the | ||
| 275 | module will be called hid-icade. | ||
| 276 | |||
| 268 | config HID_TWINHAN | 277 | config HID_TWINHAN |
| 269 | tristate "Twinhan IR remote control" | 278 | tristate "Twinhan IR remote control" |
| 270 | depends on USB_HID | 279 | depends on USB_HID |
| @@ -728,4 +737,6 @@ endif # HID | |||
| 728 | 737 | ||
| 729 | source "drivers/hid/usbhid/Kconfig" | 738 | source "drivers/hid/usbhid/Kconfig" |
| 730 | 739 | ||
| 740 | source "drivers/hid/i2c-hid/Kconfig" | ||
| 741 | |||
| 731 | endmenu | 742 | endmenu |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index cef68ca859d3..b62215716b2f 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
| @@ -52,6 +52,7 @@ obj-$(CONFIG_HID_GYRATION) += hid-gyration.o | |||
| 52 | obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o | 52 | obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o |
| 53 | obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o | 53 | obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o |
| 54 | obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o | 54 | obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o |
| 55 | obj-$(CONFIG_HID_ICADE) += hid-icade.o | ||
| 55 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o | 56 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o |
| 56 | obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o | 57 | obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o |
| 57 | obj-$(CONFIG_HID_KYE) += hid-kye.o | 58 | obj-$(CONFIG_HID_KYE) += hid-kye.o |
| @@ -93,8 +94,8 @@ obj-$(CONFIG_HID_PRIMAX) += hid-primax.o | |||
| 93 | obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o | 94 | obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o |
| 94 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ | 95 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ |
| 95 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ | 96 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ |
| 96 | hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o \ | 97 | hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-lua.o \ |
| 97 | hid-roccat-savu.o | 98 | hid-roccat-pyra.o hid-roccat-savu.o |
| 98 | obj-$(CONFIG_HID_SAITEK) += hid-saitek.o | 99 | obj-$(CONFIG_HID_SAITEK) += hid-saitek.o |
| 99 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o | 100 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o |
| 100 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o | 101 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o |
| @@ -118,3 +119,4 @@ obj-$(CONFIG_USB_HID) += usbhid/ | |||
| 118 | obj-$(CONFIG_USB_MOUSE) += usbhid/ | 119 | obj-$(CONFIG_USB_MOUSE) += usbhid/ |
| 119 | obj-$(CONFIG_USB_KBD) += usbhid/ | 120 | obj-$(CONFIG_USB_KBD) += usbhid/ |
| 120 | 121 | ||
| 122 | obj-$(CONFIG_I2C_HID) += i2c-hid/ | ||
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index fd7722aecf77..d0f7662aacca 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c | |||
| @@ -439,7 +439,8 @@ static const struct hid_device_id apple_devices[] = { | |||
| 439 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI), | 439 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI), |
| 440 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 440 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
| 441 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO), | 441 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO), |
| 442 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 442 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
| 443 | APPLE_ISO_KEYBOARD }, | ||
| 443 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS), | 444 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS), |
| 444 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | | 445 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | |
| 445 | APPLE_RDESC_JIS }, | 446 | APPLE_RDESC_JIS }, |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b5974cd45968..eb2ee11b6412 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -725,7 +725,12 @@ static int hid_scan_report(struct hid_device *hid) | |||
| 725 | hid_scan_usage(hid, u); | 725 | hid_scan_usage(hid, u); |
| 726 | break; | 726 | break; |
| 727 | } | 727 | } |
| 728 | } | 728 | } else if (page == HID_UP_SENSOR && |
| 729 | item.type == HID_ITEM_TYPE_MAIN && | ||
| 730 | item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION && | ||
| 731 | (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL && | ||
| 732 | hid->bus == BUS_USB) | ||
| 733 | hid->group = HID_GROUP_SENSOR_HUB; | ||
| 729 | } | 734 | } |
| 730 | 735 | ||
| 731 | return 0; | 736 | return 0; |
| @@ -1483,6 +1488,10 @@ EXPORT_SYMBOL_GPL(hid_disconnect); | |||
| 1483 | * there is a proper autodetection and autoloading in place (based on presence | 1488 | * there is a proper autodetection and autoloading in place (based on presence |
| 1484 | * of HID_DG_CONTACTID), so those devices don't need to be added to this list, | 1489 | * of HID_DG_CONTACTID), so those devices don't need to be added to this list, |
| 1485 | * as we are doing the right thing in hid_scan_usage(). | 1490 | * as we are doing the right thing in hid_scan_usage(). |
| 1491 | * | ||
| 1492 | * Autodetection for (USB) HID sensor hubs exists too. If a collection of type | ||
| 1493 | * physical is found inside a usage page of type sensor, hid-sensor-hub will be | ||
| 1494 | * used as a driver. See hid_scan_report(). | ||
| 1486 | */ | 1495 | */ |
| 1487 | static const struct hid_device_id hid_have_special_driver[] = { | 1496 | static const struct hid_device_id hid_have_special_driver[] = { |
| 1488 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, | 1497 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, |
| @@ -1556,6 +1565,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1556 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, | 1565 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, |
| 1557 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, | 1566 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, |
| 1558 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, | 1567 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, |
| 1568 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI) }, | ||
| 1559 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, | 1569 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, |
| 1560 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1570 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
| 1561 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1571 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
| @@ -1589,10 +1599,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1589 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, | 1599 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, |
| 1590 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, | 1600 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, |
| 1591 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, | 1601 | { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, |
| 1592 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, USB_DEVICE_ID_SENSOR_HUB_1020) }, | 1602 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, |
| 1593 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, USB_DEVICE_ID_SENSOR_HUB_09FA) }, | ||
| 1594 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, USB_DEVICE_ID_SENSOR_HUB_1020) }, | ||
| 1595 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, USB_DEVICE_ID_SENSOR_HUB_09FA) }, | ||
| 1596 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, | 1603 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, |
| 1597 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, | 1604 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, |
| 1598 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, | 1605 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, |
| @@ -1676,6 +1683,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1676 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, | 1683 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, |
| 1677 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, | 1684 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, |
| 1678 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) }, | 1685 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) }, |
| 1686 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) }, | ||
| 1679 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, | 1687 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, |
| 1680 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) }, | 1688 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) }, |
| 1681 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) }, | 1689 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) }, |
| @@ -1690,7 +1698,6 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1690 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 1698 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, |
| 1691 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, | 1699 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, |
| 1692 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, | 1700 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, |
| 1693 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_SENSOR_HUB_7014) }, | ||
| 1694 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, | 1701 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, |
| 1695 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, | 1702 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, |
| 1696 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, | 1703 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, |
| @@ -2168,8 +2175,13 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { | |||
| 2168 | { } | 2175 | { } |
| 2169 | }; | 2176 | }; |
| 2170 | 2177 | ||
| 2171 | static bool hid_ignore(struct hid_device *hdev) | 2178 | bool hid_ignore(struct hid_device *hdev) |
| 2172 | { | 2179 | { |
| 2180 | if (hdev->quirks & HID_QUIRK_NO_IGNORE) | ||
| 2181 | return false; | ||
| 2182 | if (hdev->quirks & HID_QUIRK_IGNORE) | ||
| 2183 | return true; | ||
| 2184 | |||
| 2173 | switch (hdev->vendor) { | 2185 | switch (hdev->vendor) { |
| 2174 | case USB_VENDOR_ID_CODEMERCS: | 2186 | case USB_VENDOR_ID_CODEMERCS: |
| 2175 | /* ignore all Code Mercenaries IOWarrior devices */ | 2187 | /* ignore all Code Mercenaries IOWarrior devices */ |
| @@ -2206,7 +2218,16 @@ static bool hid_ignore(struct hid_device *hdev) | |||
| 2206 | if (hdev->product == USB_DEVICE_ID_JESS_YUREX && | 2218 | if (hdev->product == USB_DEVICE_ID_JESS_YUREX && |
| 2207 | hdev->type == HID_TYPE_USBNONE) | 2219 | hdev->type == HID_TYPE_USBNONE) |
| 2208 | return true; | 2220 | return true; |
| 2209 | break; | 2221 | break; |
| 2222 | case USB_VENDOR_ID_DWAV: | ||
| 2223 | /* These are handled by usbtouchscreen. hdev->type is probably | ||
| 2224 | * HID_TYPE_USBNONE, but we say !HID_TYPE_USBMOUSE to match | ||
| 2225 | * usbtouchscreen. */ | ||
| 2226 | if ((hdev->product == USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER || | ||
| 2227 | hdev->product == USB_DEVICE_ID_DWAV_TOUCHCONTROLLER) && | ||
| 2228 | hdev->type != HID_TYPE_USBMOUSE) | ||
| 2229 | return true; | ||
| 2230 | break; | ||
| 2210 | } | 2231 | } |
| 2211 | 2232 | ||
| 2212 | if (hdev->type == HID_TYPE_USBMOUSE && | 2233 | if (hdev->type == HID_TYPE_USBMOUSE && |
| @@ -2215,6 +2236,7 @@ static bool hid_ignore(struct hid_device *hdev) | |||
| 2215 | 2236 | ||
| 2216 | return !!hid_match_id(hdev, hid_ignore_list); | 2237 | return !!hid_match_id(hdev, hid_ignore_list); |
| 2217 | } | 2238 | } |
| 2239 | EXPORT_SYMBOL_GPL(hid_ignore); | ||
| 2218 | 2240 | ||
| 2219 | int hid_add_device(struct hid_device *hdev) | 2241 | int hid_add_device(struct hid_device *hdev) |
| 2220 | { | 2242 | { |
| @@ -2226,8 +2248,7 @@ int hid_add_device(struct hid_device *hdev) | |||
| 2226 | 2248 | ||
| 2227 | /* we need to kill them here, otherwise they will stay allocated to | 2249 | /* we need to kill them here, otherwise they will stay allocated to |
| 2228 | * wait for coming driver */ | 2250 | * wait for coming driver */ |
| 2229 | if (!(hdev->quirks & HID_QUIRK_NO_IGNORE) | 2251 | if (hid_ignore(hdev)) |
| 2230 | && (hid_ignore(hdev) || (hdev->quirks & HID_QUIRK_IGNORE))) | ||
| 2231 | return -ENODEV; | 2252 | return -ENODEV; |
| 2232 | 2253 | ||
| 2233 | /* | 2254 | /* |
diff --git a/drivers/hid/hid-icade.c b/drivers/hid/hid-icade.c new file mode 100644 index 000000000000..1d6565e37ba3 --- /dev/null +++ b/drivers/hid/hid-icade.c | |||
| @@ -0,0 +1,259 @@ | |||
| 1 | /* | ||
| 2 | * ION iCade input driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 Bastien Nocera <hadess@hadess.net> | ||
| 5 | * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | /* | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the Free | ||
| 11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 12 | * any later version. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/hid.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | |||
| 19 | #include "hid-ids.h" | ||
| 20 | |||
| 21 | /* | ||
| 22 | * ↑ A C Y L | ||
| 23 | * ← → | ||
| 24 | * ↓ B X Z R | ||
| 25 | * | ||
| 26 | * | ||
| 27 | * UP ON,OFF = w,e | ||
| 28 | * RT ON,OFF = d,c | ||
| 29 | * DN ON,OFF = x,z | ||
| 30 | * LT ON,OFF = a,q | ||
| 31 | * A ON,OFF = y,t | ||
| 32 | * B ON,OFF = h,r | ||
| 33 | * C ON,OFF = u,f | ||
| 34 | * X ON,OFF = j,n | ||
| 35 | * Y ON,OFF = i,m | ||
| 36 | * Z ON,OFF = k,p | ||
| 37 | * L ON,OFF = o,g | ||
| 38 | * R ON,OFF = l,v | ||
| 39 | */ | ||
| 40 | |||
| 41 | /* The translation code uses HID usage instead of input layer | ||
| 42 | * keys. This code generates a lookup table that makes | ||
| 43 | * translation quick. | ||
| 44 | * | ||
| 45 | * #include <linux/input.h> | ||
| 46 | * #include <stdio.h> | ||
| 47 | * #include <assert.h> | ||
| 48 | * | ||
| 49 | * #define unk KEY_UNKNOWN | ||
| 50 | * | ||
| 51 | * < copy of hid_keyboard[] from hid-input.c > | ||
| 52 | * | ||
| 53 | * struct icade_key_translation { | ||
| 54 | * int from; | ||
| 55 | * const char *to; | ||
| 56 | * int press; | ||
| 57 | * }; | ||
| 58 | * | ||
| 59 | * static const struct icade_key_translation icade_keys[] = { | ||
| 60 | * { KEY_W, "KEY_UP", 1 }, | ||
| 61 | * { KEY_E, "KEY_UP", 0 }, | ||
| 62 | * { KEY_D, "KEY_RIGHT", 1 }, | ||
| 63 | * { KEY_C, "KEY_RIGHT", 0 }, | ||
| 64 | * { KEY_X, "KEY_DOWN", 1 }, | ||
| 65 | * { KEY_Z, "KEY_DOWN", 0 }, | ||
| 66 | * { KEY_A, "KEY_LEFT", 1 }, | ||
| 67 | * { KEY_Q, "KEY_LEFT", 0 }, | ||
| 68 | * { KEY_Y, "BTN_A", 1 }, | ||
| 69 | * { KEY_T, "BTN_A", 0 }, | ||
| 70 | * { KEY_H, "BTN_B", 1 }, | ||
| 71 | * { KEY_R, "BTN_B", 0 }, | ||
| 72 | * { KEY_U, "BTN_C", 1 }, | ||
| 73 | * { KEY_F, "BTN_C", 0 }, | ||
| 74 | * { KEY_J, "BTN_X", 1 }, | ||
| 75 | * { KEY_N, "BTN_X", 0 }, | ||
| 76 | * { KEY_I, "BTN_Y", 1 }, | ||
| 77 | * { KEY_M, "BTN_Y", 0 }, | ||
| 78 | * { KEY_K, "BTN_Z", 1 }, | ||
| 79 | * { KEY_P, "BTN_Z", 0 }, | ||
| 80 | * { KEY_O, "BTN_THUMBL", 1 }, | ||
| 81 | * { KEY_G, "BTN_THUMBL", 0 }, | ||
| 82 | * { KEY_L, "BTN_THUMBR", 1 }, | ||
| 83 | * { KEY_V, "BTN_THUMBR", 0 }, | ||
| 84 | * | ||
| 85 | * { } | ||
| 86 | * }; | ||
| 87 | * | ||
| 88 | * static int | ||
| 89 | * usage_for_key (int key) | ||
| 90 | * { | ||
| 91 | * int i; | ||
| 92 | * for (i = 0; i < 256; i++) { | ||
| 93 | * if (hid_keyboard[i] == key) | ||
| 94 | * return i; | ||
| 95 | * } | ||
| 96 | * assert(0); | ||
| 97 | * } | ||
| 98 | * | ||
| 99 | * int main (int argc, char **argv) | ||
| 100 | * { | ||
| 101 | * const struct icade_key_translation *trans; | ||
| 102 | * int max_usage = 0; | ||
| 103 | * | ||
| 104 | * for (trans = icade_keys; trans->from; trans++) { | ||
| 105 | * int usage = usage_for_key (trans->from); | ||
| 106 | * max_usage = usage > max_usage ? usage : max_usage; | ||
| 107 | * } | ||
| 108 | * | ||
| 109 | * printf ("#define ICADE_MAX_USAGE %d\n\n", max_usage); | ||
| 110 | * printf ("struct icade_key {\n"); | ||
| 111 | * printf ("\tu16 to;\n"); | ||
| 112 | * printf ("\tu8 press:1;\n"); | ||
| 113 | * printf ("};\n\n"); | ||
| 114 | * printf ("static const struct icade_key " | ||
| 115 | * "icade_usage_table[%d] = {\n", max_usage + 1); | ||
| 116 | * for (trans = icade_keys; trans->from; trans++) { | ||
| 117 | * printf ("\t[%d] = { %s, %d },\n", | ||
| 118 | * usage_for_key (trans->from), trans->to, trans->press); | ||
| 119 | * } | ||
| 120 | * printf ("};\n"); | ||
| 121 | * | ||
| 122 | * return 0; | ||
| 123 | * } | ||
| 124 | */ | ||
| 125 | |||
| 126 | #define ICADE_MAX_USAGE 29 | ||
| 127 | |||
| 128 | struct icade_key { | ||
| 129 | u16 to; | ||
| 130 | u8 press:1; | ||
| 131 | }; | ||
| 132 | |||
| 133 | static const struct icade_key icade_usage_table[30] = { | ||
| 134 | [26] = { KEY_UP, 1 }, | ||
| 135 | [8] = { KEY_UP, 0 }, | ||
| 136 | [7] = { KEY_RIGHT, 1 }, | ||
| 137 | [6] = { KEY_RIGHT, 0 }, | ||
| 138 | [27] = { KEY_DOWN, 1 }, | ||
| 139 | [29] = { KEY_DOWN, 0 }, | ||
| 140 | [4] = { KEY_LEFT, 1 }, | ||
| 141 | [20] = { KEY_LEFT, 0 }, | ||
| 142 | [28] = { BTN_A, 1 }, | ||
| 143 | [23] = { BTN_A, 0 }, | ||
| 144 | [11] = { BTN_B, 1 }, | ||
| 145 | [21] = { BTN_B, 0 }, | ||
| 146 | [24] = { BTN_C, 1 }, | ||
| 147 | [9] = { BTN_C, 0 }, | ||
| 148 | [13] = { BTN_X, 1 }, | ||
| 149 | [17] = { BTN_X, 0 }, | ||
| 150 | [12] = { BTN_Y, 1 }, | ||
| 151 | [16] = { BTN_Y, 0 }, | ||
| 152 | [14] = { BTN_Z, 1 }, | ||
| 153 | [19] = { BTN_Z, 0 }, | ||
| 154 | [18] = { BTN_THUMBL, 1 }, | ||
| 155 | [10] = { BTN_THUMBL, 0 }, | ||
| 156 | [15] = { BTN_THUMBR, 1 }, | ||
| 157 | [25] = { BTN_THUMBR, 0 }, | ||
| 158 | }; | ||
| 159 | |||
| 160 | static const struct icade_key *icade_find_translation(u16 from) | ||
| 161 | { | ||
| 162 | if (from < 0 || from > ICADE_MAX_USAGE) | ||
| 163 | return NULL; | ||
| 164 | return &icade_usage_table[from]; | ||
| 165 | } | ||
| 166 | |||
| 167 | static int icade_event(struct hid_device *hdev, struct hid_field *field, | ||
| 168 | struct hid_usage *usage, __s32 value) | ||
| 169 | { | ||
| 170 | const struct icade_key *trans; | ||
| 171 | |||
| 172 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || | ||
| 173 | !usage->type) | ||
| 174 | return 0; | ||
| 175 | |||
| 176 | /* We ignore the fake key up, and act only on key down */ | ||
| 177 | if (!value) | ||
| 178 | return 1; | ||
| 179 | |||
| 180 | trans = icade_find_translation(usage->hid & HID_USAGE); | ||
| 181 | |||
| 182 | if (!trans) | ||
| 183 | return 1; | ||
| 184 | |||
| 185 | input_event(field->hidinput->input, usage->type, | ||
| 186 | trans->to, trans->press); | ||
| 187 | |||
| 188 | return 1; | ||
| 189 | } | ||
| 190 | |||
| 191 | static int icade_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
| 192 | struct hid_field *field, struct hid_usage *usage, | ||
| 193 | unsigned long **bit, int *max) | ||
| 194 | { | ||
| 195 | const struct icade_key *trans; | ||
| 196 | |||
| 197 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_KEYBOARD) { | ||
| 198 | trans = icade_find_translation(usage->hid & HID_USAGE); | ||
| 199 | |||
| 200 | if (!trans) | ||
| 201 | return -1; | ||
| 202 | |||
| 203 | hid_map_usage(hi, usage, bit, max, EV_KEY, trans->to); | ||
| 204 | set_bit(trans->to, hi->input->keybit); | ||
| 205 | |||
| 206 | return 1; | ||
| 207 | } | ||
| 208 | |||
| 209 | /* ignore others */ | ||
| 210 | return -1; | ||
| 211 | |||
| 212 | } | ||
| 213 | |||
| 214 | static int icade_input_mapped(struct hid_device *hdev, struct hid_input *hi, | ||
| 215 | struct hid_field *field, struct hid_usage *usage, | ||
| 216 | unsigned long **bit, int *max) | ||
| 217 | { | ||
| 218 | if (usage->type == EV_KEY) | ||
| 219 | set_bit(usage->type, hi->input->evbit); | ||
| 220 | |||
| 221 | return -1; | ||
| 222 | } | ||
| 223 | |||
| 224 | static const struct hid_device_id icade_devices[] = { | ||
| 225 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, | ||
| 226 | |||
| 227 | { } | ||
| 228 | }; | ||
| 229 | MODULE_DEVICE_TABLE(hid, icade_devices); | ||
| 230 | |||
| 231 | static struct hid_driver icade_driver = { | ||
| 232 | .name = "icade", | ||
| 233 | .id_table = icade_devices, | ||
| 234 | .event = icade_event, | ||
| 235 | .input_mapped = icade_input_mapped, | ||
| 236 | .input_mapping = icade_input_mapping, | ||
| 237 | }; | ||
| 238 | |||
| 239 | static int __init icade_init(void) | ||
| 240 | { | ||
| 241 | int ret; | ||
| 242 | |||
| 243 | ret = hid_register_driver(&icade_driver); | ||
| 244 | if (ret) | ||
| 245 | pr_err("can't register icade driver\n"); | ||
| 246 | |||
| 247 | return ret; | ||
| 248 | } | ||
| 249 | |||
| 250 | static void __exit icade_exit(void) | ||
| 251 | { | ||
| 252 | hid_unregister_driver(&icade_driver); | ||
| 253 | } | ||
| 254 | |||
| 255 | module_init(icade_init); | ||
| 256 | module_exit(icade_exit); | ||
| 257 | MODULE_LICENSE("GPL"); | ||
| 258 | MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>"); | ||
| 259 | MODULE_DESCRIPTION("ION iCade input driver"); | ||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 9d7a42857ea1..4dfa605e2d14 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -257,6 +257,7 @@ | |||
| 257 | 257 | ||
| 258 | #define USB_VENDOR_ID_DWAV 0x0eef | 258 | #define USB_VENDOR_ID_DWAV 0x0eef |
| 259 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 | 259 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 |
| 260 | #define USB_DEVICE_ID_DWAV_TOUCHCONTROLLER 0x0002 | ||
| 260 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d | 261 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d |
| 261 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e | 262 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e |
| 262 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207 0x7207 | 263 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207 0x7207 |
| @@ -423,6 +424,9 @@ | |||
| 423 | #define USB_VENDOR_ID_ILITEK 0x222a | 424 | #define USB_VENDOR_ID_ILITEK 0x222a |
| 424 | #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 | 425 | #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 |
| 425 | 426 | ||
| 427 | #define USB_VENDOR_ID_ION 0x15e4 | ||
| 428 | #define USB_DEVICE_ID_ICADE 0x0132 | ||
| 429 | |||
| 426 | #define USB_VENDOR_ID_HOLTEK 0x1241 | 430 | #define USB_VENDOR_ID_HOLTEK 0x1241 |
| 427 | #define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015 | 431 | #define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015 |
| 428 | 432 | ||
| @@ -432,11 +436,6 @@ | |||
| 432 | #define USB_VENDOR_ID_IMATION 0x0718 | 436 | #define USB_VENDOR_ID_IMATION 0x0718 |
| 433 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 | 437 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 |
| 434 | 438 | ||
| 435 | #define USB_VENDOR_ID_INTEL_8086 0x8086 | ||
| 436 | #define USB_VENDOR_ID_INTEL_8087 0x8087 | ||
| 437 | #define USB_DEVICE_ID_SENSOR_HUB_1020 0x1020 | ||
| 438 | #define USB_DEVICE_ID_SENSOR_HUB_09FA 0x09FA | ||
| 439 | |||
| 440 | #define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 | 439 | #define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 |
| 441 | #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 | 440 | #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 |
| 442 | 441 | ||
| @@ -603,6 +602,7 @@ | |||
| 603 | 602 | ||
| 604 | #define USB_VENDOR_ID_NOVATEK 0x0603 | 603 | #define USB_VENDOR_ID_NOVATEK 0x0603 |
| 605 | #define USB_DEVICE_ID_NOVATEK_PCT 0x0600 | 604 | #define USB_DEVICE_ID_NOVATEK_PCT 0x0600 |
| 605 | #define USB_DEVICE_ID_NOVATEK_MOUSE 0x1602 | ||
| 606 | 606 | ||
| 607 | #define USB_VENDOR_ID_NTRIG 0x1b96 | 607 | #define USB_VENDOR_ID_NTRIG 0x1b96 |
| 608 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 | 608 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 |
| @@ -677,7 +677,9 @@ | |||
| 677 | #define USB_DEVICE_ID_ROCCAT_ISKU 0x319c | 677 | #define USB_DEVICE_ID_ROCCAT_ISKU 0x319c |
| 678 | #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced | 678 | #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced |
| 679 | #define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51 | 679 | #define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51 |
| 680 | #define USB_DEVICE_ID_ROCCAT_KONEXTD 0x2e22 | ||
| 680 | #define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50 | 681 | #define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50 |
| 682 | #define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e | ||
| 681 | #define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24 | 683 | #define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24 |
| 682 | #define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6 | 684 | #define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6 |
| 683 | #define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a | 685 | #define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a |
| @@ -696,6 +698,9 @@ | |||
| 696 | #define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f | 698 | #define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f |
| 697 | #define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002 | 699 | #define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002 |
| 698 | 700 | ||
| 701 | #define USB_VENDOR_ID_SIGMATEL 0x066F | ||
| 702 | #define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780 | ||
| 703 | |||
| 699 | #define USB_VENDOR_ID_SKYCABLE 0x1223 | 704 | #define USB_VENDOR_ID_SKYCABLE 0x1223 |
| 700 | #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 | 705 | #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 |
| 701 | 706 | ||
| @@ -714,7 +719,6 @@ | |||
| 714 | 719 | ||
| 715 | #define USB_VENDOR_ID_STANTUM_STM 0x0483 | 720 | #define USB_VENDOR_ID_STANTUM_STM 0x0483 |
| 716 | #define USB_DEVICE_ID_MTP_STM 0x3261 | 721 | #define USB_DEVICE_ID_MTP_STM 0x3261 |
| 717 | #define USB_DEVICE_ID_SENSOR_HUB_7014 0x7014 | ||
| 718 | 722 | ||
| 719 | #define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403 | 723 | #define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403 |
| 720 | #define USB_DEVICE_ID_MTP_SITRONIX 0x5001 | 724 | #define USB_DEVICE_ID_MTP_SITRONIX 0x5001 |
| @@ -762,6 +766,9 @@ | |||
| 762 | #define USB_VENDOR_ID_TOUCHPACK 0x1bfd | 766 | #define USB_VENDOR_ID_TOUCHPACK 0x1bfd |
| 763 | #define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 | 767 | #define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 |
| 764 | 768 | ||
| 769 | #define USB_VENDOR_ID_TPV 0x25aa | ||
| 770 | #define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN 0x8883 | ||
| 771 | |||
| 765 | #define USB_VENDOR_ID_TURBOX 0x062a | 772 | #define USB_VENDOR_ID_TURBOX 0x062a |
| 766 | #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 | 773 | #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 |
| 767 | #define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART 0x7100 | 774 | #define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART 0x7100 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 007a9433bfa7..21b196c394b1 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
| @@ -311,6 +311,9 @@ static enum power_supply_property hidinput_battery_props[] = { | |||
| 311 | 311 | ||
| 312 | static const struct hid_device_id hid_battery_quirks[] = { | 312 | static const struct hid_device_id hid_battery_quirks[] = { |
| 313 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | 313 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
| 314 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), | ||
| 315 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | ||
| 316 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
| 314 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), | 317 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), |
| 315 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | 318 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, |
| 316 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | 319 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
| @@ -514,9 +517,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
| 514 | if (code <= 0xf) | 517 | if (code <= 0xf) |
| 515 | code += BTN_JOYSTICK; | 518 | code += BTN_JOYSTICK; |
| 516 | else | 519 | else |
| 517 | code += BTN_TRIGGER_HAPPY; | 520 | code += BTN_TRIGGER_HAPPY - 0x10; |
| 521 | break; | ||
| 522 | case HID_GD_GAMEPAD: | ||
| 523 | if (code <= 0xf) | ||
| 524 | code += BTN_GAMEPAD; | ||
| 525 | else | ||
| 526 | code += BTN_TRIGGER_HAPPY - 0x10; | ||
| 518 | break; | 527 | break; |
| 519 | case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break; | ||
| 520 | default: | 528 | default: |
| 521 | switch (field->physical) { | 529 | switch (field->physical) { |
| 522 | case HID_GD_MOUSE: | 530 | case HID_GD_MOUSE: |
| @@ -1158,6 +1166,38 @@ static void report_features(struct hid_device *hid) | |||
| 1158 | } | 1166 | } |
| 1159 | } | 1167 | } |
| 1160 | 1168 | ||
| 1169 | static struct hid_input *hidinput_allocate(struct hid_device *hid) | ||
| 1170 | { | ||
| 1171 | struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); | ||
| 1172 | struct input_dev *input_dev = input_allocate_device(); | ||
| 1173 | if (!hidinput || !input_dev) { | ||
| 1174 | kfree(hidinput); | ||
| 1175 | input_free_device(input_dev); | ||
| 1176 | hid_err(hid, "Out of memory during hid input probe\n"); | ||
| 1177 | return NULL; | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | input_set_drvdata(input_dev, hid); | ||
| 1181 | input_dev->event = hid->ll_driver->hidinput_input_event; | ||
| 1182 | input_dev->open = hidinput_open; | ||
| 1183 | input_dev->close = hidinput_close; | ||
| 1184 | input_dev->setkeycode = hidinput_setkeycode; | ||
| 1185 | input_dev->getkeycode = hidinput_getkeycode; | ||
| 1186 | |||
| 1187 | input_dev->name = hid->name; | ||
| 1188 | input_dev->phys = hid->phys; | ||
| 1189 | input_dev->uniq = hid->uniq; | ||
| 1190 | input_dev->id.bustype = hid->bus; | ||
| 1191 | input_dev->id.vendor = hid->vendor; | ||
| 1192 | input_dev->id.product = hid->product; | ||
| 1193 | input_dev->id.version = hid->version; | ||
| 1194 | input_dev->dev.parent = hid->dev.parent; | ||
| 1195 | hidinput->input = input_dev; | ||
| 1196 | list_add_tail(&hidinput->list, &hid->inputs); | ||
| 1197 | |||
| 1198 | return hidinput; | ||
| 1199 | } | ||
| 1200 | |||
| 1161 | /* | 1201 | /* |
| 1162 | * Register the input device; print a message. | 1202 | * Register the input device; print a message. |
| 1163 | * Configure the input layer interface | 1203 | * Configure the input layer interface |
| @@ -1169,7 +1209,6 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
| 1169 | struct hid_driver *drv = hid->driver; | 1209 | struct hid_driver *drv = hid->driver; |
| 1170 | struct hid_report *report; | 1210 | struct hid_report *report; |
| 1171 | struct hid_input *hidinput = NULL; | 1211 | struct hid_input *hidinput = NULL; |
| 1172 | struct input_dev *input_dev; | ||
| 1173 | int i, j, k; | 1212 | int i, j, k; |
| 1174 | 1213 | ||
| 1175 | INIT_LIST_HEAD(&hid->inputs); | 1214 | INIT_LIST_HEAD(&hid->inputs); |
| @@ -1200,33 +1239,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
| 1200 | continue; | 1239 | continue; |
| 1201 | 1240 | ||
| 1202 | if (!hidinput) { | 1241 | if (!hidinput) { |
| 1203 | hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); | 1242 | hidinput = hidinput_allocate(hid); |
| 1204 | input_dev = input_allocate_device(); | 1243 | if (!hidinput) |
| 1205 | if (!hidinput || !input_dev) { | ||
| 1206 | kfree(hidinput); | ||
| 1207 | input_free_device(input_dev); | ||
| 1208 | hid_err(hid, "Out of memory during hid input probe\n"); | ||
| 1209 | goto out_unwind; | 1244 | goto out_unwind; |
| 1210 | } | ||
| 1211 | |||
| 1212 | input_set_drvdata(input_dev, hid); | ||
| 1213 | input_dev->event = | ||
| 1214 | hid->ll_driver->hidinput_input_event; | ||
| 1215 | input_dev->open = hidinput_open; | ||
| 1216 | input_dev->close = hidinput_close; | ||
| 1217 | input_dev->setkeycode = hidinput_setkeycode; | ||
| 1218 | input_dev->getkeycode = hidinput_getkeycode; | ||
| 1219 | |||
| 1220 | input_dev->name = hid->name; | ||
| 1221 | input_dev->phys = hid->phys; | ||
| 1222 | input_dev->uniq = hid->uniq; | ||
| 1223 | input_dev->id.bustype = hid->bus; | ||
| 1224 | input_dev->id.vendor = hid->vendor; | ||
| 1225 | input_dev->id.product = hid->product; | ||
| 1226 | input_dev->id.version = hid->version; | ||
| 1227 | input_dev->dev.parent = hid->dev.parent; | ||
| 1228 | hidinput->input = input_dev; | ||
| 1229 | list_add_tail(&hidinput->list, &hid->inputs); | ||
| 1230 | } | 1245 | } |
| 1231 | 1246 | ||
| 1232 | for (i = 0; i < report->maxfield; i++) | 1247 | for (i = 0; i < report->maxfield; i++) |
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index f676c01bb471..6fcd466d0825 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
| @@ -46,9 +46,9 @@ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 46 | rdesc[559] = 0x45; | 46 | rdesc[559] = 0x45; |
| 47 | } | 47 | } |
| 48 | /* the same as above (s/usage/physical/) */ | 48 | /* the same as above (s/usage/physical/) */ |
| 49 | if ((quirks & MS_RDESC_3K) && *rsize == 106 && | 49 | if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 && |
| 50 | !memcmp((char []){ 0x19, 0x00, 0x29, 0xff }, | 50 | rdesc[95] == 0x00 && rdesc[96] == 0x29 && |
| 51 | &rdesc[94], 4)) { | 51 | rdesc[97] == 0xff) { |
| 52 | rdesc[94] = 0x35; | 52 | rdesc[94] = 0x35; |
| 53 | rdesc[96] = 0x45; | 53 | rdesc[96] = 0x45; |
| 54 | } | 54 | } |
diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index 5669916c2943..1219998a02d6 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c | |||
| @@ -167,7 +167,7 @@ static ssize_t isku_sysfs_write_ ## thingy(struct file *fp, struct kobject *kobj | |||
| 167 | loff_t off, size_t count) \ | 167 | loff_t off, size_t count) \ |
| 168 | { \ | 168 | { \ |
| 169 | return isku_sysfs_write(fp, kobj, buf, off, count, \ | 169 | return isku_sysfs_write(fp, kobj, buf, off, count, \ |
| 170 | sizeof(struct isku_ ## thingy), ISKU_COMMAND_ ## THINGY); \ | 170 | ISKU_SIZE_ ## THINGY, ISKU_COMMAND_ ## THINGY); \ |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | #define ISKU_SYSFS_R(thingy, THINGY) \ | 173 | #define ISKU_SYSFS_R(thingy, THINGY) \ |
| @@ -176,32 +176,32 @@ static ssize_t isku_sysfs_read_ ## thingy(struct file *fp, struct kobject *kobj, | |||
| 176 | loff_t off, size_t count) \ | 176 | loff_t off, size_t count) \ |
| 177 | { \ | 177 | { \ |
| 178 | return isku_sysfs_read(fp, kobj, buf, off, count, \ | 178 | return isku_sysfs_read(fp, kobj, buf, off, count, \ |
| 179 | sizeof(struct isku_ ## thingy), ISKU_COMMAND_ ## THINGY); \ | 179 | ISKU_SIZE_ ## THINGY, ISKU_COMMAND_ ## THINGY); \ |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | #define ISKU_SYSFS_RW(thingy, THINGY) \ | 182 | #define ISKU_SYSFS_RW(thingy, THINGY) \ |
| 183 | ISKU_SYSFS_R(thingy, THINGY) \ | 183 | ISKU_SYSFS_R(thingy, THINGY) \ |
| 184 | ISKU_SYSFS_W(thingy, THINGY) | 184 | ISKU_SYSFS_W(thingy, THINGY) |
| 185 | 185 | ||
| 186 | #define ISKU_BIN_ATTR_RW(thingy) \ | 186 | #define ISKU_BIN_ATTR_RW(thingy, THINGY) \ |
| 187 | { \ | 187 | { \ |
| 188 | .attr = { .name = #thingy, .mode = 0660 }, \ | 188 | .attr = { .name = #thingy, .mode = 0660 }, \ |
| 189 | .size = sizeof(struct isku_ ## thingy), \ | 189 | .size = ISKU_SIZE_ ## THINGY, \ |
| 190 | .read = isku_sysfs_read_ ## thingy, \ | 190 | .read = isku_sysfs_read_ ## thingy, \ |
| 191 | .write = isku_sysfs_write_ ## thingy \ | 191 | .write = isku_sysfs_write_ ## thingy \ |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | #define ISKU_BIN_ATTR_R(thingy) \ | 194 | #define ISKU_BIN_ATTR_R(thingy, THINGY) \ |
| 195 | { \ | 195 | { \ |
| 196 | .attr = { .name = #thingy, .mode = 0440 }, \ | 196 | .attr = { .name = #thingy, .mode = 0440 }, \ |
| 197 | .size = sizeof(struct isku_ ## thingy), \ | 197 | .size = ISKU_SIZE_ ## THINGY, \ |
| 198 | .read = isku_sysfs_read_ ## thingy, \ | 198 | .read = isku_sysfs_read_ ## thingy, \ |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | #define ISKU_BIN_ATTR_W(thingy) \ | 201 | #define ISKU_BIN_ATTR_W(thingy, THINGY) \ |
| 202 | { \ | 202 | { \ |
| 203 | .attr = { .name = #thingy, .mode = 0220 }, \ | 203 | .attr = { .name = #thingy, .mode = 0220 }, \ |
| 204 | .size = sizeof(struct isku_ ## thingy), \ | 204 | .size = ISKU_SIZE_ ## THINGY, \ |
| 205 | .write = isku_sysfs_write_ ## thingy \ | 205 | .write = isku_sysfs_write_ ## thingy \ |
| 206 | } | 206 | } |
| 207 | 207 | ||
| @@ -218,21 +218,23 @@ ISKU_SYSFS_RW(last_set, LAST_SET) | |||
| 218 | ISKU_SYSFS_W(talk, TALK) | 218 | ISKU_SYSFS_W(talk, TALK) |
| 219 | ISKU_SYSFS_R(info, INFO) | 219 | ISKU_SYSFS_R(info, INFO) |
| 220 | ISKU_SYSFS_W(control, CONTROL) | 220 | ISKU_SYSFS_W(control, CONTROL) |
| 221 | ISKU_SYSFS_W(reset, RESET) | ||
| 221 | 222 | ||
| 222 | static struct bin_attribute isku_bin_attributes[] = { | 223 | static struct bin_attribute isku_bin_attributes[] = { |
| 223 | ISKU_BIN_ATTR_RW(macro), | 224 | ISKU_BIN_ATTR_RW(macro, MACRO), |
| 224 | ISKU_BIN_ATTR_RW(keys_function), | 225 | ISKU_BIN_ATTR_RW(keys_function, KEYS_FUNCTION), |
| 225 | ISKU_BIN_ATTR_RW(keys_easyzone), | 226 | ISKU_BIN_ATTR_RW(keys_easyzone, KEYS_EASYZONE), |
| 226 | ISKU_BIN_ATTR_RW(keys_media), | 227 | ISKU_BIN_ATTR_RW(keys_media, KEYS_MEDIA), |
| 227 | ISKU_BIN_ATTR_RW(keys_thumbster), | 228 | ISKU_BIN_ATTR_RW(keys_thumbster, KEYS_THUMBSTER), |
| 228 | ISKU_BIN_ATTR_RW(keys_macro), | 229 | ISKU_BIN_ATTR_RW(keys_macro, KEYS_MACRO), |
| 229 | ISKU_BIN_ATTR_RW(keys_capslock), | 230 | ISKU_BIN_ATTR_RW(keys_capslock, KEYS_CAPSLOCK), |
| 230 | ISKU_BIN_ATTR_RW(light), | 231 | ISKU_BIN_ATTR_RW(light, LIGHT), |
| 231 | ISKU_BIN_ATTR_RW(key_mask), | 232 | ISKU_BIN_ATTR_RW(key_mask, KEY_MASK), |
| 232 | ISKU_BIN_ATTR_RW(last_set), | 233 | ISKU_BIN_ATTR_RW(last_set, LAST_SET), |
| 233 | ISKU_BIN_ATTR_W(talk), | 234 | ISKU_BIN_ATTR_W(talk, TALK), |
| 234 | ISKU_BIN_ATTR_R(info), | 235 | ISKU_BIN_ATTR_R(info, INFO), |
| 235 | ISKU_BIN_ATTR_W(control), | 236 | ISKU_BIN_ATTR_W(control, CONTROL), |
| 237 | ISKU_BIN_ATTR_W(reset, RESET), | ||
| 236 | __ATTR_NULL | 238 | __ATTR_NULL |
| 237 | }; | 239 | }; |
| 238 | 240 | ||
diff --git a/drivers/hid/hid-roccat-isku.h b/drivers/hid/hid-roccat-isku.h index 605b3ce21638..cf6896c83867 100644 --- a/drivers/hid/hid-roccat-isku.h +++ b/drivers/hid/hid-roccat-isku.h | |||
| @@ -15,76 +15,33 @@ | |||
| 15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 16 | 16 | ||
| 17 | enum { | 17 | enum { |
| 18 | ISKU_SIZE_CONTROL = 0x03, | ||
| 19 | ISKU_SIZE_INFO = 0x06, | ||
| 20 | ISKU_SIZE_KEY_MASK = 0x06, | ||
| 21 | ISKU_SIZE_KEYS_FUNCTION = 0x29, | ||
| 22 | ISKU_SIZE_KEYS_EASYZONE = 0x41, | ||
| 23 | ISKU_SIZE_KEYS_MEDIA = 0x1d, | ||
| 24 | ISKU_SIZE_KEYS_THUMBSTER = 0x17, | ||
| 25 | ISKU_SIZE_KEYS_MACRO = 0x23, | ||
| 26 | ISKU_SIZE_KEYS_CAPSLOCK = 0x06, | ||
| 27 | ISKU_SIZE_LAST_SET = 0x14, | ||
| 28 | ISKU_SIZE_LIGHT = 0x0a, | ||
| 29 | ISKU_SIZE_MACRO = 0x823, | ||
| 30 | ISKU_SIZE_RESET = 0x03, | ||
| 31 | ISKU_SIZE_TALK = 0x10, | ||
| 32 | }; | ||
| 33 | |||
| 34 | enum { | ||
| 18 | ISKU_PROFILE_NUM = 5, | 35 | ISKU_PROFILE_NUM = 5, |
| 19 | ISKU_USB_INTERFACE_PROTOCOL = 0, | 36 | ISKU_USB_INTERFACE_PROTOCOL = 0, |
| 20 | }; | 37 | }; |
| 21 | 38 | ||
| 22 | struct isku_control { | ||
| 23 | uint8_t command; /* ISKU_COMMAND_CONTROL */ | ||
| 24 | uint8_t value; | ||
| 25 | uint8_t request; | ||
| 26 | } __packed; | ||
| 27 | |||
| 28 | struct isku_actual_profile { | 39 | struct isku_actual_profile { |
| 29 | uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */ | 40 | uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */ |
| 30 | uint8_t size; /* always 3 */ | 41 | uint8_t size; /* always 3 */ |
| 31 | uint8_t actual_profile; | 42 | uint8_t actual_profile; |
| 32 | } __packed; | 43 | } __packed; |
| 33 | 44 | ||
| 34 | struct isku_key_mask { | ||
| 35 | uint8_t command; /* ISKU_COMMAND_KEY_MASK */ | ||
| 36 | uint8_t size; /* 6 */ | ||
| 37 | uint8_t profile_number; /* 0-4 */ | ||
| 38 | uint8_t mask; | ||
| 39 | uint16_t checksum; | ||
| 40 | } __packed; | ||
| 41 | |||
| 42 | struct isku_keys_function { | ||
| 43 | uint8_t data[0x29]; | ||
| 44 | } __packed; | ||
| 45 | |||
| 46 | struct isku_keys_easyzone { | ||
| 47 | uint8_t data[0x41]; | ||
| 48 | } __packed; | ||
| 49 | |||
| 50 | struct isku_keys_media { | ||
| 51 | uint8_t data[0x1d]; | ||
| 52 | } __packed; | ||
| 53 | |||
| 54 | struct isku_keys_thumbster { | ||
| 55 | uint8_t data[0x17]; | ||
| 56 | } __packed; | ||
| 57 | |||
| 58 | struct isku_keys_macro { | ||
| 59 | uint8_t data[0x23]; | ||
| 60 | } __packed; | ||
| 61 | |||
| 62 | struct isku_keys_capslock { | ||
| 63 | uint8_t data[0x6]; | ||
| 64 | } __packed; | ||
| 65 | |||
| 66 | struct isku_macro { | ||
| 67 | uint8_t data[0x823]; | ||
| 68 | } __packed; | ||
| 69 | |||
| 70 | struct isku_light { | ||
| 71 | uint8_t data[0xa]; | ||
| 72 | } __packed; | ||
| 73 | |||
| 74 | struct isku_info { | ||
| 75 | uint8_t data[2]; | ||
| 76 | uint8_t firmware_version; | ||
| 77 | uint8_t unknown[3]; | ||
| 78 | } __packed; | ||
| 79 | |||
| 80 | struct isku_talk { | ||
| 81 | uint8_t data[0x10]; | ||
| 82 | } __packed; | ||
| 83 | |||
| 84 | struct isku_last_set { | ||
| 85 | uint8_t data[0x14]; | ||
| 86 | } __packed; | ||
| 87 | |||
| 88 | enum isku_commands { | 45 | enum isku_commands { |
| 89 | ISKU_COMMAND_CONTROL = 0x4, | 46 | ISKU_COMMAND_CONTROL = 0x4, |
| 90 | ISKU_COMMAND_ACTUAL_PROFILE = 0x5, | 47 | ISKU_COMMAND_ACTUAL_PROFILE = 0x5, |
| @@ -97,6 +54,7 @@ enum isku_commands { | |||
| 97 | ISKU_COMMAND_MACRO = 0xe, | 54 | ISKU_COMMAND_MACRO = 0xe, |
| 98 | ISKU_COMMAND_INFO = 0xf, | 55 | ISKU_COMMAND_INFO = 0xf, |
| 99 | ISKU_COMMAND_LIGHT = 0x10, | 56 | ISKU_COMMAND_LIGHT = 0x10, |
| 57 | ISKU_COMMAND_RESET = 0x11, | ||
| 100 | ISKU_COMMAND_KEYS_CAPSLOCK = 0x13, | 58 | ISKU_COMMAND_KEYS_CAPSLOCK = 0x13, |
| 101 | ISKU_COMMAND_LAST_SET = 0x14, | 59 | ISKU_COMMAND_LAST_SET = 0x14, |
| 102 | ISKU_COMMAND_15 = 0x15, | 60 | ISKU_COMMAND_15 = 0x15, |
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index f5602fec4865..6a48fa3c7da9 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | /* | 14 | /* |
| 15 | * Roccat Kone[+] is an updated/improved version of the Kone with more memory | 15 | * Roccat Kone[+] is an updated/improved version of the Kone with more memory |
| 16 | * and functionality and without the non-standard behaviours the Kone had. | 16 | * and functionality and without the non-standard behaviours the Kone had. |
| 17 | * KoneXTD has same capabilities but updated sensor. | ||
| 17 | */ | 18 | */ |
| 18 | 19 | ||
| 19 | #include <linux/device.h> | 20 | #include <linux/device.h> |
| @@ -55,56 +56,6 @@ static int koneplus_send_control(struct usb_device *usb_dev, uint value, | |||
| 55 | &control, sizeof(struct roccat_common2_control)); | 56 | &control, sizeof(struct roccat_common2_control)); |
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | static int koneplus_get_info(struct usb_device *usb_dev, | ||
| 59 | struct koneplus_info *buf) | ||
| 60 | { | ||
| 61 | return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO, | ||
| 62 | buf, sizeof(struct koneplus_info)); | ||
| 63 | } | ||
| 64 | |||
| 65 | static int koneplus_get_profile_settings(struct usb_device *usb_dev, | ||
| 66 | struct koneplus_profile_settings *buf, uint number) | ||
| 67 | { | ||
| 68 | int retval; | ||
| 69 | |||
| 70 | retval = koneplus_send_control(usb_dev, number, | ||
| 71 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); | ||
| 72 | if (retval) | ||
| 73 | return retval; | ||
| 74 | |||
| 75 | return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS, | ||
| 76 | buf, sizeof(struct koneplus_profile_settings)); | ||
| 77 | } | ||
| 78 | |||
| 79 | static int koneplus_set_profile_settings(struct usb_device *usb_dev, | ||
| 80 | struct koneplus_profile_settings const *settings) | ||
| 81 | { | ||
| 82 | return roccat_common2_send_with_status(usb_dev, | ||
| 83 | KONEPLUS_COMMAND_PROFILE_SETTINGS, | ||
| 84 | settings, sizeof(struct koneplus_profile_settings)); | ||
| 85 | } | ||
| 86 | |||
| 87 | static int koneplus_get_profile_buttons(struct usb_device *usb_dev, | ||
| 88 | struct koneplus_profile_buttons *buf, int number) | ||
| 89 | { | ||
| 90 | int retval; | ||
| 91 | |||
| 92 | retval = koneplus_send_control(usb_dev, number, | ||
| 93 | KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); | ||
| 94 | if (retval) | ||
| 95 | return retval; | ||
| 96 | |||
| 97 | return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS, | ||
| 98 | buf, sizeof(struct koneplus_profile_buttons)); | ||
| 99 | } | ||
| 100 | |||
| 101 | static int koneplus_set_profile_buttons(struct usb_device *usb_dev, | ||
| 102 | struct koneplus_profile_buttons const *buttons) | ||
| 103 | { | ||
| 104 | return roccat_common2_send_with_status(usb_dev, | ||
| 105 | KONEPLUS_COMMAND_PROFILE_BUTTONS, | ||
| 106 | buttons, sizeof(struct koneplus_profile_buttons)); | ||
| 107 | } | ||
| 108 | 59 | ||
| 109 | /* retval is 0-4 on success, < 0 on error */ | 60 | /* retval is 0-4 on success, < 0 on error */ |
| 110 | static int koneplus_get_actual_profile(struct usb_device *usb_dev) | 61 | static int koneplus_get_actual_profile(struct usb_device *usb_dev) |
| @@ -113,7 +64,7 @@ static int koneplus_get_actual_profile(struct usb_device *usb_dev) | |||
| 113 | int retval; | 64 | int retval; |
| 114 | 65 | ||
| 115 | retval = roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, | 66 | retval = roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, |
| 116 | &buf, sizeof(struct koneplus_actual_profile)); | 67 | &buf, KONEPLUS_SIZE_ACTUAL_PROFILE); |
| 117 | 68 | ||
| 118 | return retval ? retval : buf.actual_profile; | 69 | return retval ? retval : buf.actual_profile; |
| 119 | } | 70 | } |
| @@ -124,12 +75,12 @@ static int koneplus_set_actual_profile(struct usb_device *usb_dev, | |||
| 124 | struct koneplus_actual_profile buf; | 75 | struct koneplus_actual_profile buf; |
| 125 | 76 | ||
| 126 | buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE; | 77 | buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE; |
| 127 | buf.size = sizeof(struct koneplus_actual_profile); | 78 | buf.size = KONEPLUS_SIZE_ACTUAL_PROFILE; |
| 128 | buf.actual_profile = new_profile; | 79 | buf.actual_profile = new_profile; |
| 129 | 80 | ||
| 130 | return roccat_common2_send_with_status(usb_dev, | 81 | return roccat_common2_send_with_status(usb_dev, |
| 131 | KONEPLUS_COMMAND_ACTUAL_PROFILE, | 82 | KONEPLUS_COMMAND_ACTUAL_PROFILE, |
| 132 | &buf, sizeof(struct koneplus_actual_profile)); | 83 | &buf, KONEPLUS_SIZE_ACTUAL_PROFILE); |
| 133 | } | 84 | } |
| 134 | 85 | ||
| 135 | static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, | 86 | static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, |
| @@ -182,111 +133,77 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj, | |||
| 182 | return real_size; | 133 | return real_size; |
| 183 | } | 134 | } |
| 184 | 135 | ||
| 185 | static ssize_t koneplus_sysfs_write_talk(struct file *fp, | 136 | #define KONEPLUS_SYSFS_W(thingy, THINGY) \ |
| 186 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 137 | static ssize_t koneplus_sysfs_write_ ## thingy(struct file *fp, \ |
| 187 | loff_t off, size_t count) | 138 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ |
| 188 | { | 139 | loff_t off, size_t count) \ |
| 189 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | 140 | { \ |
| 190 | sizeof(struct koneplus_talk), KONEPLUS_COMMAND_TALK); | 141 | return koneplus_sysfs_write(fp, kobj, buf, off, count, \ |
| 142 | KONEPLUS_SIZE_ ## THINGY, KONEPLUS_COMMAND_ ## THINGY); \ | ||
| 191 | } | 143 | } |
| 192 | 144 | ||
| 193 | static ssize_t koneplus_sysfs_write_macro(struct file *fp, | 145 | #define KONEPLUS_SYSFS_R(thingy, THINGY) \ |
| 194 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 146 | static ssize_t koneplus_sysfs_read_ ## thingy(struct file *fp, \ |
| 195 | loff_t off, size_t count) | 147 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ |
| 196 | { | 148 | loff_t off, size_t count) \ |
| 197 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | 149 | { \ |
| 198 | sizeof(struct koneplus_macro), KONEPLUS_COMMAND_MACRO); | 150 | return koneplus_sysfs_read(fp, kobj, buf, off, count, \ |
| 151 | KONEPLUS_SIZE_ ## THINGY, KONEPLUS_COMMAND_ ## THINGY); \ | ||
| 199 | } | 152 | } |
| 200 | 153 | ||
| 201 | static ssize_t koneplus_sysfs_read_sensor(struct file *fp, | 154 | #define KONEPLUS_SYSFS_RW(thingy, THINGY) \ |
| 202 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 155 | KONEPLUS_SYSFS_W(thingy, THINGY) \ |
| 203 | loff_t off, size_t count) | 156 | KONEPLUS_SYSFS_R(thingy, THINGY) |
| 204 | { | ||
| 205 | return koneplus_sysfs_read(fp, kobj, buf, off, count, | ||
| 206 | sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR); | ||
| 207 | } | ||
| 208 | 157 | ||
| 209 | static ssize_t koneplus_sysfs_write_sensor(struct file *fp, | 158 | #define KONEPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \ |
| 210 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 159 | { \ |
| 211 | loff_t off, size_t count) | 160 | .attr = { .name = #thingy, .mode = 0660 }, \ |
| 212 | { | 161 | .size = KONEPLUS_SIZE_ ## THINGY, \ |
| 213 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | 162 | .read = koneplus_sysfs_read_ ## thingy, \ |
| 214 | sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR); | 163 | .write = koneplus_sysfs_write_ ## thingy \ |
| 215 | } | 164 | } |
| 216 | 165 | ||
| 217 | static ssize_t koneplus_sysfs_write_tcu(struct file *fp, | 166 | #define KONEPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \ |
| 218 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 167 | { \ |
| 219 | loff_t off, size_t count) | 168 | .attr = { .name = #thingy, .mode = 0440 }, \ |
| 220 | { | 169 | .size = KONEPLUS_SIZE_ ## THINGY, \ |
| 221 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | 170 | .read = koneplus_sysfs_read_ ## thingy, \ |
| 222 | sizeof(struct koneplus_tcu), KONEPLUS_COMMAND_TCU); | ||
| 223 | } | 171 | } |
| 224 | 172 | ||
| 225 | static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp, | 173 | #define KONEPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \ |
| 226 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 174 | { \ |
| 227 | loff_t off, size_t count) | 175 | .attr = { .name = #thingy, .mode = 0220 }, \ |
| 228 | { | 176 | .size = KONEPLUS_SIZE_ ## THINGY, \ |
| 229 | return koneplus_sysfs_read(fp, kobj, buf, off, count, | 177 | .write = koneplus_sysfs_write_ ## thingy \ |
| 230 | sizeof(struct koneplus_tcu_image), KONEPLUS_COMMAND_TCU); | ||
| 231 | } | 178 | } |
| 232 | 179 | ||
| 233 | static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, | 180 | KONEPLUS_SYSFS_W(control, CONTROL) |
| 234 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 181 | KONEPLUS_SYSFS_RW(info, INFO) |
| 235 | loff_t off, size_t count) | 182 | KONEPLUS_SYSFS_W(talk, TALK) |
| 236 | { | 183 | KONEPLUS_SYSFS_W(macro, MACRO) |
| 237 | struct device *dev = | 184 | KONEPLUS_SYSFS_RW(sensor, SENSOR) |
| 238 | container_of(kobj, struct device, kobj)->parent->parent; | 185 | KONEPLUS_SYSFS_RW(tcu, TCU) |
| 239 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | 186 | KONEPLUS_SYSFS_R(tcu_image, TCU_IMAGE) |
| 240 | 187 | KONEPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS) | |
| 241 | if (off >= sizeof(struct koneplus_profile_settings)) | 188 | KONEPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS) |
| 242 | return 0; | ||
| 243 | 189 | ||
| 244 | if (off + count > sizeof(struct koneplus_profile_settings)) | 190 | static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, |
| 245 | count = sizeof(struct koneplus_profile_settings) - off; | ||
| 246 | |||
| 247 | mutex_lock(&koneplus->koneplus_lock); | ||
| 248 | memcpy(buf, ((char const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off, | ||
| 249 | count); | ||
| 250 | mutex_unlock(&koneplus->koneplus_lock); | ||
| 251 | |||
| 252 | return count; | ||
| 253 | } | ||
| 254 | |||
| 255 | static ssize_t koneplus_sysfs_write_profile_settings(struct file *fp, | ||
| 256 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 191 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
| 257 | loff_t off, size_t count) | 192 | loff_t off, size_t count) |
| 258 | { | 193 | { |
| 259 | struct device *dev = | 194 | struct device *dev = |
| 260 | container_of(kobj, struct device, kobj)->parent->parent; | 195 | container_of(kobj, struct device, kobj)->parent->parent; |
| 261 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 262 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 196 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 263 | int retval = 0; | 197 | ssize_t retval; |
| 264 | int difference; | ||
| 265 | int profile_number; | ||
| 266 | struct koneplus_profile_settings *profile_settings; | ||
| 267 | |||
| 268 | if (off != 0 || count != sizeof(struct koneplus_profile_settings)) | ||
| 269 | return -EINVAL; | ||
| 270 | |||
| 271 | profile_number = ((struct koneplus_profile_settings const *)buf)->number; | ||
| 272 | profile_settings = &koneplus->profile_settings[profile_number]; | ||
| 273 | |||
| 274 | mutex_lock(&koneplus->koneplus_lock); | ||
| 275 | difference = memcmp(buf, profile_settings, | ||
| 276 | sizeof(struct koneplus_profile_settings)); | ||
| 277 | if (difference) { | ||
| 278 | retval = koneplus_set_profile_settings(usb_dev, | ||
| 279 | (struct koneplus_profile_settings const *)buf); | ||
| 280 | if (!retval) | ||
| 281 | memcpy(profile_settings, buf, | ||
| 282 | sizeof(struct koneplus_profile_settings)); | ||
| 283 | } | ||
| 284 | mutex_unlock(&koneplus->koneplus_lock); | ||
| 285 | 198 | ||
| 199 | retval = koneplus_send_control(usb_dev, *(uint *)(attr->private), | ||
| 200 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); | ||
| 286 | if (retval) | 201 | if (retval) |
| 287 | return retval; | 202 | return retval; |
| 288 | 203 | ||
| 289 | return sizeof(struct koneplus_profile_settings); | 204 | return koneplus_sysfs_read(fp, kobj, buf, off, count, |
| 205 | KONEPLUS_SIZE_PROFILE_SETTINGS, | ||
| 206 | KONEPLUS_COMMAND_PROFILE_SETTINGS); | ||
| 290 | } | 207 | } |
| 291 | 208 | ||
| 292 | static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, | 209 | static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, |
| @@ -295,57 +212,17 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, | |||
| 295 | { | 212 | { |
| 296 | struct device *dev = | 213 | struct device *dev = |
| 297 | container_of(kobj, struct device, kobj)->parent->parent; | 214 | container_of(kobj, struct device, kobj)->parent->parent; |
| 298 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 299 | |||
| 300 | if (off >= sizeof(struct koneplus_profile_buttons)) | ||
| 301 | return 0; | ||
| 302 | |||
| 303 | if (off + count > sizeof(struct koneplus_profile_buttons)) | ||
| 304 | count = sizeof(struct koneplus_profile_buttons) - off; | ||
| 305 | |||
| 306 | mutex_lock(&koneplus->koneplus_lock); | ||
| 307 | memcpy(buf, ((char const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off, | ||
| 308 | count); | ||
| 309 | mutex_unlock(&koneplus->koneplus_lock); | ||
| 310 | |||
| 311 | return count; | ||
| 312 | } | ||
| 313 | |||
| 314 | static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp, | ||
| 315 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | ||
| 316 | loff_t off, size_t count) | ||
| 317 | { | ||
| 318 | struct device *dev = | ||
| 319 | container_of(kobj, struct device, kobj)->parent->parent; | ||
| 320 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 321 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 215 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 322 | int retval = 0; | 216 | ssize_t retval; |
| 323 | int difference; | ||
| 324 | uint profile_number; | ||
| 325 | struct koneplus_profile_buttons *profile_buttons; | ||
| 326 | |||
| 327 | if (off != 0 || count != sizeof(struct koneplus_profile_buttons)) | ||
| 328 | return -EINVAL; | ||
| 329 | |||
| 330 | profile_number = ((struct koneplus_profile_buttons const *)buf)->number; | ||
| 331 | profile_buttons = &koneplus->profile_buttons[profile_number]; | ||
| 332 | |||
| 333 | mutex_lock(&koneplus->koneplus_lock); | ||
| 334 | difference = memcmp(buf, profile_buttons, | ||
| 335 | sizeof(struct koneplus_profile_buttons)); | ||
| 336 | if (difference) { | ||
| 337 | retval = koneplus_set_profile_buttons(usb_dev, | ||
| 338 | (struct koneplus_profile_buttons const *)buf); | ||
| 339 | if (!retval) | ||
| 340 | memcpy(profile_buttons, buf, | ||
| 341 | sizeof(struct koneplus_profile_buttons)); | ||
| 342 | } | ||
| 343 | mutex_unlock(&koneplus->koneplus_lock); | ||
| 344 | 217 | ||
| 218 | retval = koneplus_send_control(usb_dev, *(uint *)(attr->private), | ||
| 219 | KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); | ||
| 345 | if (retval) | 220 | if (retval) |
| 346 | return retval; | 221 | return retval; |
| 347 | 222 | ||
| 348 | return sizeof(struct koneplus_profile_buttons); | 223 | return koneplus_sysfs_read(fp, kobj, buf, off, count, |
| 224 | KONEPLUS_SIZE_PROFILE_BUTTONS, | ||
| 225 | KONEPLUS_COMMAND_PROFILE_BUTTONS); | ||
| 349 | } | 226 | } |
| 350 | 227 | ||
| 351 | static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, | 228 | static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, |
| @@ -401,9 +278,20 @@ static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev, | |||
| 401 | static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, | 278 | static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, |
| 402 | struct device_attribute *attr, char *buf) | 279 | struct device_attribute *attr, char *buf) |
| 403 | { | 280 | { |
| 404 | struct koneplus_device *koneplus = | 281 | struct koneplus_device *koneplus; |
| 405 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 282 | struct usb_device *usb_dev; |
| 406 | return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->info.firmware_version); | 283 | struct koneplus_info info; |
| 284 | |||
| 285 | dev = dev->parent->parent; | ||
| 286 | koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 287 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 288 | |||
| 289 | mutex_lock(&koneplus->koneplus_lock); | ||
| 290 | roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO, | ||
| 291 | &info, KONEPLUS_SIZE_INFO); | ||
| 292 | mutex_unlock(&koneplus->koneplus_lock); | ||
| 293 | |||
| 294 | return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); | ||
| 407 | } | 295 | } |
| 408 | 296 | ||
| 409 | static struct device_attribute koneplus_attributes[] = { | 297 | static struct device_attribute koneplus_attributes[] = { |
| @@ -419,132 +307,85 @@ static struct device_attribute koneplus_attributes[] = { | |||
| 419 | }; | 307 | }; |
| 420 | 308 | ||
| 421 | static struct bin_attribute koneplus_bin_attributes[] = { | 309 | static struct bin_attribute koneplus_bin_attributes[] = { |
| 422 | { | 310 | KONEPLUS_BIN_ATTRIBUTE_W(control, CONTROL), |
| 423 | .attr = { .name = "sensor", .mode = 0660 }, | 311 | KONEPLUS_BIN_ATTRIBUTE_RW(info, INFO), |
| 424 | .size = sizeof(struct koneplus_sensor), | 312 | KONEPLUS_BIN_ATTRIBUTE_W(talk, TALK), |
| 425 | .read = koneplus_sysfs_read_sensor, | 313 | KONEPLUS_BIN_ATTRIBUTE_W(macro, MACRO), |
| 426 | .write = koneplus_sysfs_write_sensor | 314 | KONEPLUS_BIN_ATTRIBUTE_RW(sensor, SENSOR), |
| 427 | }, | 315 | KONEPLUS_BIN_ATTRIBUTE_RW(tcu, TCU), |
| 428 | { | 316 | KONEPLUS_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE), |
| 429 | .attr = { .name = "tcu", .mode = 0220 }, | 317 | KONEPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS), |
| 430 | .size = sizeof(struct koneplus_tcu), | 318 | KONEPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS), |
| 431 | .write = koneplus_sysfs_write_tcu | ||
| 432 | }, | ||
| 433 | { | ||
| 434 | .attr = { .name = "tcu_image", .mode = 0440 }, | ||
| 435 | .size = sizeof(struct koneplus_tcu_image), | ||
| 436 | .read = koneplus_sysfs_read_tcu_image | ||
| 437 | }, | ||
| 438 | { | ||
| 439 | .attr = { .name = "profile_settings", .mode = 0220 }, | ||
| 440 | .size = sizeof(struct koneplus_profile_settings), | ||
| 441 | .write = koneplus_sysfs_write_profile_settings | ||
| 442 | }, | ||
| 443 | { | 319 | { |
| 444 | .attr = { .name = "profile1_settings", .mode = 0440 }, | 320 | .attr = { .name = "profile1_settings", .mode = 0440 }, |
| 445 | .size = sizeof(struct koneplus_profile_settings), | 321 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, |
| 446 | .read = koneplus_sysfs_read_profilex_settings, | 322 | .read = koneplus_sysfs_read_profilex_settings, |
| 447 | .private = &profile_numbers[0] | 323 | .private = &profile_numbers[0] |
| 448 | }, | 324 | }, |
| 449 | { | 325 | { |
| 450 | .attr = { .name = "profile2_settings", .mode = 0440 }, | 326 | .attr = { .name = "profile2_settings", .mode = 0440 }, |
| 451 | .size = sizeof(struct koneplus_profile_settings), | 327 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, |
| 452 | .read = koneplus_sysfs_read_profilex_settings, | 328 | .read = koneplus_sysfs_read_profilex_settings, |
| 453 | .private = &profile_numbers[1] | 329 | .private = &profile_numbers[1] |
| 454 | }, | 330 | }, |
| 455 | { | 331 | { |
| 456 | .attr = { .name = "profile3_settings", .mode = 0440 }, | 332 | .attr = { .name = "profile3_settings", .mode = 0440 }, |
| 457 | .size = sizeof(struct koneplus_profile_settings), | 333 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, |
| 458 | .read = koneplus_sysfs_read_profilex_settings, | 334 | .read = koneplus_sysfs_read_profilex_settings, |
| 459 | .private = &profile_numbers[2] | 335 | .private = &profile_numbers[2] |
| 460 | }, | 336 | }, |
| 461 | { | 337 | { |
| 462 | .attr = { .name = "profile4_settings", .mode = 0440 }, | 338 | .attr = { .name = "profile4_settings", .mode = 0440 }, |
| 463 | .size = sizeof(struct koneplus_profile_settings), | 339 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, |
| 464 | .read = koneplus_sysfs_read_profilex_settings, | 340 | .read = koneplus_sysfs_read_profilex_settings, |
| 465 | .private = &profile_numbers[3] | 341 | .private = &profile_numbers[3] |
| 466 | }, | 342 | }, |
| 467 | { | 343 | { |
| 468 | .attr = { .name = "profile5_settings", .mode = 0440 }, | 344 | .attr = { .name = "profile5_settings", .mode = 0440 }, |
| 469 | .size = sizeof(struct koneplus_profile_settings), | 345 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, |
| 470 | .read = koneplus_sysfs_read_profilex_settings, | 346 | .read = koneplus_sysfs_read_profilex_settings, |
| 471 | .private = &profile_numbers[4] | 347 | .private = &profile_numbers[4] |
| 472 | }, | 348 | }, |
| 473 | { | 349 | { |
| 474 | .attr = { .name = "profile_buttons", .mode = 0220 }, | ||
| 475 | .size = sizeof(struct koneplus_profile_buttons), | ||
| 476 | .write = koneplus_sysfs_write_profile_buttons | ||
| 477 | }, | ||
| 478 | { | ||
| 479 | .attr = { .name = "profile1_buttons", .mode = 0440 }, | 350 | .attr = { .name = "profile1_buttons", .mode = 0440 }, |
| 480 | .size = sizeof(struct koneplus_profile_buttons), | 351 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, |
| 481 | .read = koneplus_sysfs_read_profilex_buttons, | 352 | .read = koneplus_sysfs_read_profilex_buttons, |
| 482 | .private = &profile_numbers[0] | 353 | .private = &profile_numbers[0] |
| 483 | }, | 354 | }, |
| 484 | { | 355 | { |
| 485 | .attr = { .name = "profile2_buttons", .mode = 0440 }, | 356 | .attr = { .name = "profile2_buttons", .mode = 0440 }, |
| 486 | .size = sizeof(struct koneplus_profile_buttons), | 357 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, |
| 487 | .read = koneplus_sysfs_read_profilex_buttons, | 358 | .read = koneplus_sysfs_read_profilex_buttons, |
| 488 | .private = &profile_numbers[1] | 359 | .private = &profile_numbers[1] |
| 489 | }, | 360 | }, |
| 490 | { | 361 | { |
| 491 | .attr = { .name = "profile3_buttons", .mode = 0440 }, | 362 | .attr = { .name = "profile3_buttons", .mode = 0440 }, |
| 492 | .size = sizeof(struct koneplus_profile_buttons), | 363 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, |
| 493 | .read = koneplus_sysfs_read_profilex_buttons, | 364 | .read = koneplus_sysfs_read_profilex_buttons, |
| 494 | .private = &profile_numbers[2] | 365 | .private = &profile_numbers[2] |
| 495 | }, | 366 | }, |
| 496 | { | 367 | { |
| 497 | .attr = { .name = "profile4_buttons", .mode = 0440 }, | 368 | .attr = { .name = "profile4_buttons", .mode = 0440 }, |
| 498 | .size = sizeof(struct koneplus_profile_buttons), | 369 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, |
| 499 | .read = koneplus_sysfs_read_profilex_buttons, | 370 | .read = koneplus_sysfs_read_profilex_buttons, |
| 500 | .private = &profile_numbers[3] | 371 | .private = &profile_numbers[3] |
| 501 | }, | 372 | }, |
| 502 | { | 373 | { |
| 503 | .attr = { .name = "profile5_buttons", .mode = 0440 }, | 374 | .attr = { .name = "profile5_buttons", .mode = 0440 }, |
| 504 | .size = sizeof(struct koneplus_profile_buttons), | 375 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, |
| 505 | .read = koneplus_sysfs_read_profilex_buttons, | 376 | .read = koneplus_sysfs_read_profilex_buttons, |
| 506 | .private = &profile_numbers[4] | 377 | .private = &profile_numbers[4] |
| 507 | }, | 378 | }, |
| 508 | { | ||
| 509 | .attr = { .name = "macro", .mode = 0220 }, | ||
| 510 | .size = sizeof(struct koneplus_macro), | ||
| 511 | .write = koneplus_sysfs_write_macro | ||
| 512 | }, | ||
| 513 | { | ||
| 514 | .attr = { .name = "talk", .mode = 0220 }, | ||
| 515 | .size = sizeof(struct koneplus_talk), | ||
| 516 | .write = koneplus_sysfs_write_talk | ||
| 517 | }, | ||
| 518 | __ATTR_NULL | 379 | __ATTR_NULL |
| 519 | }; | 380 | }; |
| 520 | 381 | ||
| 521 | static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, | 382 | static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, |
| 522 | struct koneplus_device *koneplus) | 383 | struct koneplus_device *koneplus) |
| 523 | { | 384 | { |
| 524 | int retval, i; | 385 | int retval; |
| 525 | static uint wait = 200; | ||
| 526 | 386 | ||
| 527 | mutex_init(&koneplus->koneplus_lock); | 387 | mutex_init(&koneplus->koneplus_lock); |
| 528 | 388 | ||
| 529 | retval = koneplus_get_info(usb_dev, &koneplus->info); | ||
| 530 | if (retval) | ||
| 531 | return retval; | ||
| 532 | |||
| 533 | for (i = 0; i < 5; ++i) { | ||
| 534 | msleep(wait); | ||
| 535 | retval = koneplus_get_profile_settings(usb_dev, | ||
| 536 | &koneplus->profile_settings[i], i); | ||
| 537 | if (retval) | ||
| 538 | return retval; | ||
| 539 | |||
| 540 | msleep(wait); | ||
| 541 | retval = koneplus_get_profile_buttons(usb_dev, | ||
| 542 | &koneplus->profile_buttons[i], i); | ||
| 543 | if (retval) | ||
| 544 | return retval; | ||
| 545 | } | ||
| 546 | |||
| 547 | msleep(wait); | ||
| 548 | retval = koneplus_get_actual_profile(usb_dev); | 389 | retval = koneplus_get_actual_profile(usb_dev); |
| 549 | if (retval < 0) | 390 | if (retval < 0) |
| 550 | return retval; | 391 | return retval; |
| @@ -709,6 +550,7 @@ static int koneplus_raw_event(struct hid_device *hdev, | |||
| 709 | 550 | ||
| 710 | static const struct hid_device_id koneplus_devices[] = { | 551 | static const struct hid_device_id koneplus_devices[] = { |
| 711 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, | 552 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, |
| 553 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEXTD) }, | ||
| 712 | { } | 554 | { } |
| 713 | }; | 555 | }; |
| 714 | 556 | ||
| @@ -749,5 +591,5 @@ module_init(koneplus_init); | |||
| 749 | module_exit(koneplus_exit); | 591 | module_exit(koneplus_exit); |
| 750 | 592 | ||
| 751 | MODULE_AUTHOR("Stefan Achatz"); | 593 | MODULE_AUTHOR("Stefan Achatz"); |
| 752 | MODULE_DESCRIPTION("USB Roccat Kone[+] driver"); | 594 | MODULE_DESCRIPTION("USB Roccat Kone[+]/XTD driver"); |
| 753 | MODULE_LICENSE("GPL v2"); | 595 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/hid/hid-roccat-koneplus.h b/drivers/hid/hid-roccat-koneplus.h index 7074b2a4b94b..af7f57e8cf3b 100644 --- a/drivers/hid/hid-roccat-koneplus.h +++ b/drivers/hid/hid-roccat-koneplus.h | |||
| @@ -14,11 +14,19 @@ | |||
| 14 | 14 | ||
| 15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 16 | 16 | ||
| 17 | struct koneplus_talk { | 17 | enum { |
| 18 | uint8_t command; /* KONEPLUS_COMMAND_TALK */ | 18 | KONEPLUS_SIZE_ACTUAL_PROFILE = 0x03, |
| 19 | uint8_t size; /* always 0x10 */ | 19 | KONEPLUS_SIZE_CONTROL = 0x03, |
| 20 | uint8_t data[14]; | 20 | KONEPLUS_SIZE_FIRMWARE_WRITE = 0x0402, |
| 21 | } __packed; | 21 | KONEPLUS_SIZE_INFO = 0x06, |
| 22 | KONEPLUS_SIZE_MACRO = 0x0822, | ||
| 23 | KONEPLUS_SIZE_PROFILE_SETTINGS = 0x2b, | ||
| 24 | KONEPLUS_SIZE_PROFILE_BUTTONS = 0x4d, | ||
| 25 | KONEPLUS_SIZE_SENSOR = 0x06, | ||
| 26 | KONEPLUS_SIZE_TALK = 0x10, | ||
| 27 | KONEPLUS_SIZE_TCU = 0x04, | ||
| 28 | KONEPLUS_SIZE_TCU_IMAGE = 0x0404, | ||
| 29 | }; | ||
| 22 | 30 | ||
| 23 | enum koneplus_control_requests { | 31 | enum koneplus_control_requests { |
| 24 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80, | 32 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80, |
| @@ -31,45 +39,6 @@ struct koneplus_actual_profile { | |||
| 31 | uint8_t actual_profile; /* Range 0-4! */ | 39 | uint8_t actual_profile; /* Range 0-4! */ |
| 32 | } __attribute__ ((__packed__)); | 40 | } __attribute__ ((__packed__)); |
| 33 | 41 | ||
| 34 | struct koneplus_profile_settings { | ||
| 35 | uint8_t command; /* KONEPLUS_COMMAND_PROFILE_SETTINGS */ | ||
| 36 | uint8_t size; /* always 43 */ | ||
| 37 | uint8_t number; /* range 0-4 */ | ||
| 38 | uint8_t advanced_sensitivity; | ||
| 39 | uint8_t sensitivity_x; | ||
| 40 | uint8_t sensitivity_y; | ||
| 41 | uint8_t cpi_levels_enabled; | ||
| 42 | uint8_t cpi_levels_x[5]; | ||
| 43 | uint8_t cpi_startup_level; /* range 0-4 */ | ||
| 44 | uint8_t cpi_levels_y[5]; /* range 1-60 means 100-6000 cpi */ | ||
| 45 | uint8_t unknown1; | ||
| 46 | uint8_t polling_rate; | ||
| 47 | uint8_t lights_enabled; | ||
| 48 | uint8_t light_effect_mode; | ||
| 49 | uint8_t color_flow_effect; | ||
| 50 | uint8_t light_effect_type; | ||
| 51 | uint8_t light_effect_speed; | ||
| 52 | uint8_t lights[16]; | ||
| 53 | uint16_t checksum; | ||
| 54 | } __attribute__ ((__packed__)); | ||
| 55 | |||
| 56 | struct koneplus_profile_buttons { | ||
| 57 | uint8_t command; /* KONEPLUS_COMMAND_PROFILE_BUTTONS */ | ||
| 58 | uint8_t size; /* always 77 */ | ||
| 59 | uint8_t number; /* range 0-4 */ | ||
| 60 | uint8_t data[72]; | ||
| 61 | uint16_t checksum; | ||
| 62 | } __attribute__ ((__packed__)); | ||
| 63 | |||
| 64 | struct koneplus_macro { | ||
| 65 | uint8_t command; /* KONEPLUS_COMMAND_MACRO */ | ||
| 66 | uint16_t size; /* always 0x822 little endian */ | ||
| 67 | uint8_t profile; /* range 0-4 */ | ||
| 68 | uint8_t button; /* range 0-23 */ | ||
| 69 | uint8_t data[2075]; | ||
| 70 | uint16_t checksum; | ||
| 71 | } __attribute__ ((__packed__)); | ||
| 72 | |||
| 73 | struct koneplus_info { | 42 | struct koneplus_info { |
| 74 | uint8_t command; /* KONEPLUS_COMMAND_INFO */ | 43 | uint8_t command; /* KONEPLUS_COMMAND_INFO */ |
| 75 | uint8_t size; /* always 6 */ | 44 | uint8_t size; /* always 6 */ |
| @@ -77,51 +46,15 @@ struct koneplus_info { | |||
| 77 | uint8_t unknown[3]; | 46 | uint8_t unknown[3]; |
| 78 | } __attribute__ ((__packed__)); | 47 | } __attribute__ ((__packed__)); |
| 79 | 48 | ||
| 80 | struct koneplus_e { | ||
| 81 | uint8_t command; /* KONEPLUS_COMMAND_E */ | ||
| 82 | uint8_t size; /* always 3 */ | ||
| 83 | uint8_t unknown; /* TODO 1; 0 before firmware update */ | ||
| 84 | } __attribute__ ((__packed__)); | ||
| 85 | |||
| 86 | struct koneplus_sensor { | ||
| 87 | uint8_t command; /* KONEPLUS_COMMAND_SENSOR */ | ||
| 88 | uint8_t size; /* always 6 */ | ||
| 89 | uint8_t data[4]; | ||
| 90 | } __attribute__ ((__packed__)); | ||
| 91 | |||
| 92 | struct koneplus_firmware_write { | ||
| 93 | uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE */ | ||
| 94 | uint8_t unknown[1025]; | ||
| 95 | } __attribute__ ((__packed__)); | ||
| 96 | |||
| 97 | struct koneplus_firmware_write_control { | ||
| 98 | uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL */ | ||
| 99 | /* | ||
| 100 | * value is 1 on success | ||
| 101 | * 3 means "not finished yet" | ||
| 102 | */ | ||
| 103 | uint8_t value; | ||
| 104 | uint8_t unknown; /* always 0x75 */ | ||
| 105 | } __attribute__ ((__packed__)); | ||
| 106 | |||
| 107 | struct koneplus_tcu { | ||
| 108 | uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */ | ||
| 109 | uint8_t data[2]; | ||
| 110 | } __attribute__ ((__packed__)); | ||
| 111 | |||
| 112 | struct koneplus_tcu_image { | ||
| 113 | uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */ | ||
| 114 | uint8_t data[1024]; | ||
| 115 | uint16_t checksum; | ||
| 116 | } __attribute__ ((__packed__)); | ||
| 117 | |||
| 118 | enum koneplus_commands { | 49 | enum koneplus_commands { |
| 119 | KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, | 50 | KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, |
| 51 | KONEPLUS_COMMAND_CONTROL = 0x4, | ||
| 120 | KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, | 52 | KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, |
| 121 | KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, | 53 | KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, |
| 122 | KONEPLUS_COMMAND_MACRO = 0x8, | 54 | KONEPLUS_COMMAND_MACRO = 0x8, |
| 123 | KONEPLUS_COMMAND_INFO = 0x9, | 55 | KONEPLUS_COMMAND_INFO = 0x9, |
| 124 | KONEPLUS_COMMAND_TCU = 0xc, | 56 | KONEPLUS_COMMAND_TCU = 0xc, |
| 57 | KONEPLUS_COMMAND_TCU_IMAGE = 0xc, | ||
| 125 | KONEPLUS_COMMAND_E = 0xe, | 58 | KONEPLUS_COMMAND_E = 0xe, |
| 126 | KONEPLUS_COMMAND_SENSOR = 0xf, | 59 | KONEPLUS_COMMAND_SENSOR = 0xf, |
| 127 | KONEPLUS_COMMAND_TALK = 0x10, | 60 | KONEPLUS_COMMAND_TALK = 0x10, |
| @@ -187,10 +120,6 @@ struct koneplus_device { | |||
| 187 | int chrdev_minor; | 120 | int chrdev_minor; |
| 188 | 121 | ||
| 189 | struct mutex koneplus_lock; | 122 | struct mutex koneplus_lock; |
| 190 | |||
| 191 | struct koneplus_info info; | ||
| 192 | struct koneplus_profile_settings profile_settings[5]; | ||
| 193 | struct koneplus_profile_buttons profile_buttons[5]; | ||
| 194 | }; | 123 | }; |
| 195 | 124 | ||
| 196 | #endif | 125 | #endif |
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index ca6527ac655d..b8b37789b864 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c | |||
| @@ -70,13 +70,6 @@ static int kovaplus_select_profile(struct usb_device *usb_dev, uint number, | |||
| 70 | return kovaplus_send_control(usb_dev, number, request); | 70 | return kovaplus_send_control(usb_dev, number, request); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | static int kovaplus_get_info(struct usb_device *usb_dev, | ||
| 74 | struct kovaplus_info *buf) | ||
| 75 | { | ||
| 76 | return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_INFO, | ||
| 77 | buf, sizeof(struct kovaplus_info)); | ||
| 78 | } | ||
| 79 | |||
| 80 | static int kovaplus_get_profile_settings(struct usb_device *usb_dev, | 73 | static int kovaplus_get_profile_settings(struct usb_device *usb_dev, |
| 81 | struct kovaplus_profile_settings *buf, uint number) | 74 | struct kovaplus_profile_settings *buf, uint number) |
| 82 | { | 75 | { |
| @@ -88,15 +81,7 @@ static int kovaplus_get_profile_settings(struct usb_device *usb_dev, | |||
| 88 | return retval; | 81 | return retval; |
| 89 | 82 | ||
| 90 | return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, | 83 | return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, |
| 91 | buf, sizeof(struct kovaplus_profile_settings)); | 84 | buf, KOVAPLUS_SIZE_PROFILE_SETTINGS); |
| 92 | } | ||
| 93 | |||
| 94 | static int kovaplus_set_profile_settings(struct usb_device *usb_dev, | ||
| 95 | struct kovaplus_profile_settings const *settings) | ||
| 96 | { | ||
| 97 | return roccat_common2_send_with_status(usb_dev, | ||
| 98 | KOVAPLUS_COMMAND_PROFILE_SETTINGS, | ||
| 99 | settings, sizeof(struct kovaplus_profile_settings)); | ||
| 100 | } | 85 | } |
| 101 | 86 | ||
| 102 | static int kovaplus_get_profile_buttons(struct usb_device *usb_dev, | 87 | static int kovaplus_get_profile_buttons(struct usb_device *usb_dev, |
| @@ -110,15 +95,7 @@ static int kovaplus_get_profile_buttons(struct usb_device *usb_dev, | |||
| 110 | return retval; | 95 | return retval; |
| 111 | 96 | ||
| 112 | return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, | 97 | return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, |
| 113 | buf, sizeof(struct kovaplus_profile_buttons)); | 98 | buf, KOVAPLUS_SIZE_PROFILE_BUTTONS); |
| 114 | } | ||
| 115 | |||
| 116 | static int kovaplus_set_profile_buttons(struct usb_device *usb_dev, | ||
| 117 | struct kovaplus_profile_buttons const *buttons) | ||
| 118 | { | ||
| 119 | return roccat_common2_send_with_status(usb_dev, | ||
| 120 | KOVAPLUS_COMMAND_PROFILE_BUTTONS, | ||
| 121 | buttons, sizeof(struct kovaplus_profile_buttons)); | ||
| 122 | } | 99 | } |
| 123 | 100 | ||
| 124 | /* retval is 0-4 on success, < 0 on error */ | 101 | /* retval is 0-4 on success, < 0 on error */ |
| @@ -147,122 +124,141 @@ static int kovaplus_set_actual_profile(struct usb_device *usb_dev, | |||
| 147 | &buf, sizeof(struct kovaplus_actual_profile)); | 124 | &buf, sizeof(struct kovaplus_actual_profile)); |
| 148 | } | 125 | } |
| 149 | 126 | ||
| 150 | static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp, | 127 | static ssize_t kovaplus_sysfs_read(struct file *fp, struct kobject *kobj, |
| 151 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 128 | char *buf, loff_t off, size_t count, |
| 152 | loff_t off, size_t count) | 129 | size_t real_size, uint command) |
| 153 | { | 130 | { |
| 154 | struct device *dev = | 131 | struct device *dev = |
| 155 | container_of(kobj, struct device, kobj)->parent->parent; | 132 | container_of(kobj, struct device, kobj)->parent->parent; |
| 156 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); | 133 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); |
| 134 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 135 | int retval; | ||
| 157 | 136 | ||
| 158 | if (off >= sizeof(struct kovaplus_profile_settings)) | 137 | if (off >= real_size) |
| 159 | return 0; | 138 | return 0; |
| 160 | 139 | ||
| 161 | if (off + count > sizeof(struct kovaplus_profile_settings)) | 140 | if (off != 0 || count != real_size) |
| 162 | count = sizeof(struct kovaplus_profile_settings) - off; | 141 | return -EINVAL; |
| 163 | 142 | ||
| 164 | mutex_lock(&kovaplus->kovaplus_lock); | 143 | mutex_lock(&kovaplus->kovaplus_lock); |
| 165 | memcpy(buf, ((char const *)&kovaplus->profile_settings[*(uint *)(attr->private)]) + off, | 144 | retval = roccat_common2_receive(usb_dev, command, buf, real_size); |
| 166 | count); | ||
| 167 | mutex_unlock(&kovaplus->kovaplus_lock); | 145 | mutex_unlock(&kovaplus->kovaplus_lock); |
| 168 | 146 | ||
| 169 | return count; | 147 | if (retval) |
| 148 | return retval; | ||
| 149 | |||
| 150 | return real_size; | ||
| 170 | } | 151 | } |
| 171 | 152 | ||
| 172 | static ssize_t kovaplus_sysfs_write_profile_settings(struct file *fp, | 153 | static ssize_t kovaplus_sysfs_write(struct file *fp, struct kobject *kobj, |
| 173 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 154 | void const *buf, loff_t off, size_t count, |
| 174 | loff_t off, size_t count) | 155 | size_t real_size, uint command) |
| 175 | { | 156 | { |
| 176 | struct device *dev = | 157 | struct device *dev = |
| 177 | container_of(kobj, struct device, kobj)->parent->parent; | 158 | container_of(kobj, struct device, kobj)->parent->parent; |
| 178 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); | 159 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); |
| 179 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 160 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 180 | int retval = 0; | 161 | int retval; |
| 181 | int difference; | ||
| 182 | int profile_index; | ||
| 183 | struct kovaplus_profile_settings *profile_settings; | ||
| 184 | 162 | ||
| 185 | if (off != 0 || count != sizeof(struct kovaplus_profile_settings)) | 163 | if (off != 0 || count != real_size) |
| 186 | return -EINVAL; | 164 | return -EINVAL; |
| 187 | 165 | ||
| 188 | profile_index = ((struct kovaplus_profile_settings const *)buf)->profile_index; | ||
| 189 | profile_settings = &kovaplus->profile_settings[profile_index]; | ||
| 190 | |||
| 191 | mutex_lock(&kovaplus->kovaplus_lock); | 166 | mutex_lock(&kovaplus->kovaplus_lock); |
| 192 | difference = memcmp(buf, profile_settings, | 167 | retval = roccat_common2_send_with_status(usb_dev, command, |
| 193 | sizeof(struct kovaplus_profile_settings)); | 168 | buf, real_size); |
| 194 | if (difference) { | ||
| 195 | retval = kovaplus_set_profile_settings(usb_dev, | ||
| 196 | (struct kovaplus_profile_settings const *)buf); | ||
| 197 | if (!retval) | ||
| 198 | memcpy(profile_settings, buf, | ||
| 199 | sizeof(struct kovaplus_profile_settings)); | ||
| 200 | } | ||
| 201 | mutex_unlock(&kovaplus->kovaplus_lock); | 169 | mutex_unlock(&kovaplus->kovaplus_lock); |
| 202 | 170 | ||
| 203 | if (retval) | 171 | if (retval) |
| 204 | return retval; | 172 | return retval; |
| 205 | 173 | ||
| 206 | return sizeof(struct kovaplus_profile_settings); | 174 | return real_size; |
| 207 | } | 175 | } |
| 208 | 176 | ||
| 209 | static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp, | 177 | #define KOVAPLUS_SYSFS_W(thingy, THINGY) \ |
| 210 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 178 | static ssize_t kovaplus_sysfs_write_ ## thingy(struct file *fp, \ |
| 211 | loff_t off, size_t count) | 179 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ |
| 212 | { | 180 | loff_t off, size_t count) \ |
| 213 | struct device *dev = | 181 | { \ |
| 214 | container_of(kobj, struct device, kobj)->parent->parent; | 182 | return kovaplus_sysfs_write(fp, kobj, buf, off, count, \ |
| 215 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); | 183 | KOVAPLUS_SIZE_ ## THINGY, KOVAPLUS_COMMAND_ ## THINGY); \ |
| 184 | } | ||
| 216 | 185 | ||
| 217 | if (off >= sizeof(struct kovaplus_profile_buttons)) | 186 | #define KOVAPLUS_SYSFS_R(thingy, THINGY) \ |
| 218 | return 0; | 187 | static ssize_t kovaplus_sysfs_read_ ## thingy(struct file *fp, \ |
| 188 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ | ||
| 189 | loff_t off, size_t count) \ | ||
| 190 | { \ | ||
| 191 | return kovaplus_sysfs_read(fp, kobj, buf, off, count, \ | ||
| 192 | KOVAPLUS_SIZE_ ## THINGY, KOVAPLUS_COMMAND_ ## THINGY); \ | ||
| 193 | } | ||
| 219 | 194 | ||
| 220 | if (off + count > sizeof(struct kovaplus_profile_buttons)) | 195 | #define KOVAPLUS_SYSFS_RW(thingy, THINGY) \ |
| 221 | count = sizeof(struct kovaplus_profile_buttons) - off; | 196 | KOVAPLUS_SYSFS_W(thingy, THINGY) \ |
| 197 | KOVAPLUS_SYSFS_R(thingy, THINGY) | ||
| 222 | 198 | ||
| 223 | mutex_lock(&kovaplus->kovaplus_lock); | 199 | #define KOVAPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \ |
| 224 | memcpy(buf, ((char const *)&kovaplus->profile_buttons[*(uint *)(attr->private)]) + off, | 200 | { \ |
| 225 | count); | 201 | .attr = { .name = #thingy, .mode = 0660 }, \ |
| 226 | mutex_unlock(&kovaplus->kovaplus_lock); | 202 | .size = KOVAPLUS_SIZE_ ## THINGY, \ |
| 203 | .read = kovaplus_sysfs_read_ ## thingy, \ | ||
| 204 | .write = kovaplus_sysfs_write_ ## thingy \ | ||
| 205 | } | ||
| 206 | |||
| 207 | #define KOVAPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \ | ||
| 208 | { \ | ||
| 209 | .attr = { .name = #thingy, .mode = 0440 }, \ | ||
| 210 | .size = KOVAPLUS_SIZE_ ## THINGY, \ | ||
| 211 | .read = kovaplus_sysfs_read_ ## thingy, \ | ||
| 212 | } | ||
| 227 | 213 | ||
| 228 | return count; | 214 | #define KOVAPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \ |
| 215 | { \ | ||
| 216 | .attr = { .name = #thingy, .mode = 0220 }, \ | ||
| 217 | .size = KOVAPLUS_SIZE_ ## THINGY, \ | ||
| 218 | .write = kovaplus_sysfs_write_ ## thingy \ | ||
| 229 | } | 219 | } |
| 230 | 220 | ||
| 231 | static ssize_t kovaplus_sysfs_write_profile_buttons(struct file *fp, | 221 | KOVAPLUS_SYSFS_W(control, CONTROL) |
| 222 | KOVAPLUS_SYSFS_RW(info, INFO) | ||
| 223 | KOVAPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS) | ||
| 224 | KOVAPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS) | ||
| 225 | |||
| 226 | static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp, | ||
| 232 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 227 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
| 233 | loff_t off, size_t count) | 228 | loff_t off, size_t count) |
| 234 | { | 229 | { |
| 235 | struct device *dev = | 230 | struct device *dev = |
| 236 | container_of(kobj, struct device, kobj)->parent->parent; | 231 | container_of(kobj, struct device, kobj)->parent->parent; |
| 237 | struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 238 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 232 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 239 | int retval = 0; | 233 | ssize_t retval; |
| 240 | int difference; | ||
| 241 | uint profile_index; | ||
| 242 | struct kovaplus_profile_buttons *profile_buttons; | ||
| 243 | 234 | ||
| 244 | if (off != 0 || count != sizeof(struct kovaplus_profile_buttons)) | 235 | retval = kovaplus_select_profile(usb_dev, *(uint *)(attr->private), |
| 245 | return -EINVAL; | 236 | KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); |
| 237 | if (retval) | ||
| 238 | return retval; | ||
| 246 | 239 | ||
| 247 | profile_index = ((struct kovaplus_profile_buttons const *)buf)->profile_index; | 240 | return kovaplus_sysfs_read(fp, kobj, buf, off, count, |
| 248 | profile_buttons = &kovaplus->profile_buttons[profile_index]; | 241 | KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 242 | KOVAPLUS_COMMAND_PROFILE_SETTINGS); | ||
| 243 | } | ||
| 249 | 244 | ||
| 250 | mutex_lock(&kovaplus->kovaplus_lock); | 245 | static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp, |
| 251 | difference = memcmp(buf, profile_buttons, | 246 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
| 252 | sizeof(struct kovaplus_profile_buttons)); | 247 | loff_t off, size_t count) |
| 253 | if (difference) { | 248 | { |
| 254 | retval = kovaplus_set_profile_buttons(usb_dev, | 249 | struct device *dev = |
| 255 | (struct kovaplus_profile_buttons const *)buf); | 250 | container_of(kobj, struct device, kobj)->parent->parent; |
| 256 | if (!retval) | 251 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 257 | memcpy(profile_buttons, buf, | 252 | ssize_t retval; |
| 258 | sizeof(struct kovaplus_profile_buttons)); | ||
| 259 | } | ||
| 260 | mutex_unlock(&kovaplus->kovaplus_lock); | ||
| 261 | 253 | ||
| 254 | retval = kovaplus_select_profile(usb_dev, *(uint *)(attr->private), | ||
| 255 | KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); | ||
| 262 | if (retval) | 256 | if (retval) |
| 263 | return retval; | 257 | return retval; |
| 264 | 258 | ||
| 265 | return sizeof(struct kovaplus_profile_buttons); | 259 | return kovaplus_sysfs_read(fp, kobj, buf, off, count, |
| 260 | KOVAPLUS_SIZE_PROFILE_BUTTONS, | ||
| 261 | KOVAPLUS_COMMAND_PROFILE_BUTTONS); | ||
| 266 | } | 262 | } |
| 267 | 263 | ||
| 268 | static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev, | 264 | static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev, |
| @@ -342,9 +338,20 @@ static ssize_t kovaplus_sysfs_show_actual_sensitivity_y(struct device *dev, | |||
| 342 | static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev, | 338 | static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev, |
| 343 | struct device_attribute *attr, char *buf) | 339 | struct device_attribute *attr, char *buf) |
| 344 | { | 340 | { |
| 345 | struct kovaplus_device *kovaplus = | 341 | struct kovaplus_device *kovaplus; |
| 346 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 342 | struct usb_device *usb_dev; |
| 347 | return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->info.firmware_version); | 343 | struct kovaplus_info info; |
| 344 | |||
| 345 | dev = dev->parent->parent; | ||
| 346 | kovaplus = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 347 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 348 | |||
| 349 | mutex_lock(&kovaplus->kovaplus_lock); | ||
| 350 | roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_INFO, | ||
| 351 | &info, KOVAPLUS_SIZE_INFO); | ||
| 352 | mutex_unlock(&kovaplus->kovaplus_lock); | ||
| 353 | |||
| 354 | return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); | ||
| 348 | } | 355 | } |
| 349 | 356 | ||
| 350 | static struct device_attribute kovaplus_attributes[] = { | 357 | static struct device_attribute kovaplus_attributes[] = { |
| @@ -363,73 +370,67 @@ static struct device_attribute kovaplus_attributes[] = { | |||
| 363 | }; | 370 | }; |
| 364 | 371 | ||
| 365 | static struct bin_attribute kovaplus_bin_attributes[] = { | 372 | static struct bin_attribute kovaplus_bin_attributes[] = { |
| 366 | { | 373 | KOVAPLUS_BIN_ATTRIBUTE_W(control, CONTROL), |
| 367 | .attr = { .name = "profile_settings", .mode = 0220 }, | 374 | KOVAPLUS_BIN_ATTRIBUTE_RW(info, INFO), |
| 368 | .size = sizeof(struct kovaplus_profile_settings), | 375 | KOVAPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS), |
| 369 | .write = kovaplus_sysfs_write_profile_settings | 376 | KOVAPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS), |
| 370 | }, | ||
| 371 | { | 377 | { |
| 372 | .attr = { .name = "profile1_settings", .mode = 0440 }, | 378 | .attr = { .name = "profile1_settings", .mode = 0440 }, |
| 373 | .size = sizeof(struct kovaplus_profile_settings), | 379 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 374 | .read = kovaplus_sysfs_read_profilex_settings, | 380 | .read = kovaplus_sysfs_read_profilex_settings, |
| 375 | .private = &profile_numbers[0] | 381 | .private = &profile_numbers[0] |
| 376 | }, | 382 | }, |
| 377 | { | 383 | { |
| 378 | .attr = { .name = "profile2_settings", .mode = 0440 }, | 384 | .attr = { .name = "profile2_settings", .mode = 0440 }, |
| 379 | .size = sizeof(struct kovaplus_profile_settings), | 385 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 380 | .read = kovaplus_sysfs_read_profilex_settings, | 386 | .read = kovaplus_sysfs_read_profilex_settings, |
| 381 | .private = &profile_numbers[1] | 387 | .private = &profile_numbers[1] |
| 382 | }, | 388 | }, |
| 383 | { | 389 | { |
| 384 | .attr = { .name = "profile3_settings", .mode = 0440 }, | 390 | .attr = { .name = "profile3_settings", .mode = 0440 }, |
| 385 | .size = sizeof(struct kovaplus_profile_settings), | 391 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 386 | .read = kovaplus_sysfs_read_profilex_settings, | 392 | .read = kovaplus_sysfs_read_profilex_settings, |
| 387 | .private = &profile_numbers[2] | 393 | .private = &profile_numbers[2] |
| 388 | }, | 394 | }, |
| 389 | { | 395 | { |
| 390 | .attr = { .name = "profile4_settings", .mode = 0440 }, | 396 | .attr = { .name = "profile4_settings", .mode = 0440 }, |
| 391 | .size = sizeof(struct kovaplus_profile_settings), | 397 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 392 | .read = kovaplus_sysfs_read_profilex_settings, | 398 | .read = kovaplus_sysfs_read_profilex_settings, |
| 393 | .private = &profile_numbers[3] | 399 | .private = &profile_numbers[3] |
| 394 | }, | 400 | }, |
| 395 | { | 401 | { |
| 396 | .attr = { .name = "profile5_settings", .mode = 0440 }, | 402 | .attr = { .name = "profile5_settings", .mode = 0440 }, |
| 397 | .size = sizeof(struct kovaplus_profile_settings), | 403 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, |
| 398 | .read = kovaplus_sysfs_read_profilex_settings, | 404 | .read = kovaplus_sysfs_read_profilex_settings, |
| 399 | .private = &profile_numbers[4] | 405 | .private = &profile_numbers[4] |
| 400 | }, | 406 | }, |
| 401 | { | 407 | { |
| 402 | .attr = { .name = "profile_buttons", .mode = 0220 }, | ||
| 403 | .size = sizeof(struct kovaplus_profile_buttons), | ||
| 404 | .write = kovaplus_sysfs_write_profile_buttons | ||
| 405 | }, | ||
| 406 | { | ||
| 407 | .attr = { .name = "profile1_buttons", .mode = 0440 }, | 408 | .attr = { .name = "profile1_buttons", .mode = 0440 }, |
| 408 | .size = sizeof(struct kovaplus_profile_buttons), | 409 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, |
| 409 | .read = kovaplus_sysfs_read_profilex_buttons, | 410 | .read = kovaplus_sysfs_read_profilex_buttons, |
| 410 | .private = &profile_numbers[0] | 411 | .private = &profile_numbers[0] |
| 411 | }, | 412 | }, |
| 412 | { | 413 | { |
| 413 | .attr = { .name = "profile2_buttons", .mode = 0440 }, | 414 | .attr = { .name = "profile2_buttons", .mode = 0440 }, |
| 414 | .size = sizeof(struct kovaplus_profile_buttons), | 415 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, |
| 415 | .read = kovaplus_sysfs_read_profilex_buttons, | 416 | .read = kovaplus_sysfs_read_profilex_buttons, |
| 416 | .private = &profile_numbers[1] | 417 | .private = &profile_numbers[1] |
| 417 | }, | 418 | }, |
| 418 | { | 419 | { |
| 419 | .attr = { .name = "profile3_buttons", .mode = 0440 }, | 420 | .attr = { .name = "profile3_buttons", .mode = 0440 }, |
| 420 | .size = sizeof(struct kovaplus_profile_buttons), | 421 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, |
| 421 | .read = kovaplus_sysfs_read_profilex_buttons, | 422 | .read = kovaplus_sysfs_read_profilex_buttons, |
| 422 | .private = &profile_numbers[2] | 423 | .private = &profile_numbers[2] |
| 423 | }, | 424 | }, |
| 424 | { | 425 | { |
| 425 | .attr = { .name = "profile4_buttons", .mode = 0440 }, | 426 | .attr = { .name = "profile4_buttons", .mode = 0440 }, |
| 426 | .size = sizeof(struct kovaplus_profile_buttons), | 427 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, |
| 427 | .read = kovaplus_sysfs_read_profilex_buttons, | 428 | .read = kovaplus_sysfs_read_profilex_buttons, |
| 428 | .private = &profile_numbers[3] | 429 | .private = &profile_numbers[3] |
| 429 | }, | 430 | }, |
| 430 | { | 431 | { |
| 431 | .attr = { .name = "profile5_buttons", .mode = 0440 }, | 432 | .attr = { .name = "profile5_buttons", .mode = 0440 }, |
| 432 | .size = sizeof(struct kovaplus_profile_buttons), | 433 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, |
| 433 | .read = kovaplus_sysfs_read_profilex_buttons, | 434 | .read = kovaplus_sysfs_read_profilex_buttons, |
| 434 | .private = &profile_numbers[4] | 435 | .private = &profile_numbers[4] |
| 435 | }, | 436 | }, |
| @@ -444,10 +445,6 @@ static int kovaplus_init_kovaplus_device_struct(struct usb_device *usb_dev, | |||
| 444 | 445 | ||
| 445 | mutex_init(&kovaplus->kovaplus_lock); | 446 | mutex_init(&kovaplus->kovaplus_lock); |
| 446 | 447 | ||
| 447 | retval = kovaplus_get_info(usb_dev, &kovaplus->info); | ||
| 448 | if (retval) | ||
| 449 | return retval; | ||
| 450 | |||
| 451 | for (i = 0; i < 5; ++i) { | 448 | for (i = 0; i < 5; ++i) { |
| 452 | msleep(wait); | 449 | msleep(wait); |
| 453 | retval = kovaplus_get_profile_settings(usb_dev, | 450 | retval = kovaplus_get_profile_settings(usb_dev, |
diff --git a/drivers/hid/hid-roccat-kovaplus.h b/drivers/hid/hid-roccat-kovaplus.h index f82daa1cdcb9..fbb7a16a7e54 100644 --- a/drivers/hid/hid-roccat-kovaplus.h +++ b/drivers/hid/hid-roccat-kovaplus.h | |||
| @@ -14,6 +14,13 @@ | |||
| 14 | 14 | ||
| 15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 16 | 16 | ||
| 17 | enum { | ||
| 18 | KOVAPLUS_SIZE_CONTROL = 0x03, | ||
| 19 | KOVAPLUS_SIZE_INFO = 0x06, | ||
| 20 | KOVAPLUS_SIZE_PROFILE_SETTINGS = 0x10, | ||
| 21 | KOVAPLUS_SIZE_PROFILE_BUTTONS = 0x17, | ||
| 22 | }; | ||
| 23 | |||
| 17 | enum kovaplus_control_requests { | 24 | enum kovaplus_control_requests { |
| 18 | /* write; value = profile number range 0-4 */ | 25 | /* write; value = profile number range 0-4 */ |
| 19 | KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, | 26 | KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, |
| @@ -53,15 +60,9 @@ struct kovaplus_info { | |||
| 53 | uint8_t unknown[3]; | 60 | uint8_t unknown[3]; |
| 54 | } __packed; | 61 | } __packed; |
| 55 | 62 | ||
| 56 | /* writes 1 on plugin */ | ||
| 57 | struct kovaplus_a { | ||
| 58 | uint8_t command; /* KOVAPLUS_COMMAND_A */ | ||
| 59 | uint8_t size; /* 3 */ | ||
| 60 | uint8_t unknown; | ||
| 61 | } __packed; | ||
| 62 | |||
| 63 | enum kovaplus_commands { | 63 | enum kovaplus_commands { |
| 64 | KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5, | 64 | KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5, |
| 65 | KOVAPLUS_COMMAND_CONTROL = 0x4, | ||
| 65 | KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6, | 66 | KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6, |
| 66 | KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7, | 67 | KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7, |
| 67 | KOVAPLUS_COMMAND_INFO = 0x9, | 68 | KOVAPLUS_COMMAND_INFO = 0x9, |
| @@ -125,7 +126,6 @@ struct kovaplus_device { | |||
| 125 | int roccat_claimed; | 126 | int roccat_claimed; |
| 126 | int chrdev_minor; | 127 | int chrdev_minor; |
| 127 | struct mutex kovaplus_lock; | 128 | struct mutex kovaplus_lock; |
| 128 | struct kovaplus_info info; | ||
| 129 | struct kovaplus_profile_settings profile_settings[5]; | 129 | struct kovaplus_profile_settings profile_settings[5]; |
| 130 | struct kovaplus_profile_buttons profile_buttons[5]; | 130 | struct kovaplus_profile_buttons profile_buttons[5]; |
| 131 | }; | 131 | }; |
diff --git a/drivers/hid/hid-roccat-lua.c b/drivers/hid/hid-roccat-lua.c new file mode 100644 index 000000000000..5084fb4b7e91 --- /dev/null +++ b/drivers/hid/hid-roccat-lua.c | |||
| @@ -0,0 +1,227 @@ | |||
| 1 | /* | ||
| 2 | * Roccat Lua driver for Linux | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the Free | ||
| 10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 11 | * any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | /* | ||
| 15 | * Roccat Lua is a gamer mouse which cpi, button and light settings can be | ||
| 16 | * configured. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/device.h> | ||
| 20 | #include <linux/input.h> | ||
| 21 | #include <linux/hid.h> | ||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/hid-roccat.h> | ||
| 25 | #include "hid-ids.h" | ||
| 26 | #include "hid-roccat-common.h" | ||
| 27 | #include "hid-roccat-lua.h" | ||
| 28 | |||
| 29 | static ssize_t lua_sysfs_read(struct file *fp, struct kobject *kobj, | ||
| 30 | char *buf, loff_t off, size_t count, | ||
| 31 | size_t real_size, uint command) | ||
| 32 | { | ||
| 33 | struct device *dev = container_of(kobj, struct device, kobj); | ||
| 34 | struct lua_device *lua = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 35 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 36 | int retval; | ||
| 37 | |||
| 38 | if (off >= real_size) | ||
| 39 | return 0; | ||
| 40 | |||
| 41 | if (off != 0 || count != real_size) | ||
| 42 | return -EINVAL; | ||
| 43 | |||
| 44 | mutex_lock(&lua->lua_lock); | ||
| 45 | retval = roccat_common2_receive(usb_dev, command, buf, real_size); | ||
| 46 | mutex_unlock(&lua->lua_lock); | ||
| 47 | |||
| 48 | return retval ? retval : real_size; | ||
| 49 | } | ||
| 50 | |||
| 51 | static ssize_t lua_sysfs_write(struct file *fp, struct kobject *kobj, | ||
| 52 | void const *buf, loff_t off, size_t count, | ||
| 53 | size_t real_size, uint command) | ||
| 54 | { | ||
| 55 | struct device *dev = container_of(kobj, struct device, kobj); | ||
| 56 | struct lua_device *lua = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 57 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 58 | int retval; | ||
| 59 | |||
| 60 | if (off != 0 || count != real_size) | ||
| 61 | return -EINVAL; | ||
| 62 | |||
| 63 | mutex_lock(&lua->lua_lock); | ||
| 64 | retval = roccat_common2_send(usb_dev, command, (void *)buf, real_size); | ||
| 65 | mutex_unlock(&lua->lua_lock); | ||
| 66 | |||
| 67 | return retval ? retval : real_size; | ||
| 68 | } | ||
| 69 | |||
| 70 | #define LUA_SYSFS_W(thingy, THINGY) \ | ||
| 71 | static ssize_t lua_sysfs_write_ ## thingy(struct file *fp, \ | ||
| 72 | struct kobject *kobj, struct bin_attribute *attr, \ | ||
| 73 | char *buf, loff_t off, size_t count) \ | ||
| 74 | { \ | ||
| 75 | return lua_sysfs_write(fp, kobj, buf, off, count, \ | ||
| 76 | LUA_SIZE_ ## THINGY, LUA_COMMAND_ ## THINGY); \ | ||
| 77 | } | ||
| 78 | |||
| 79 | #define LUA_SYSFS_R(thingy, THINGY) \ | ||
| 80 | static ssize_t lua_sysfs_read_ ## thingy(struct file *fp, \ | ||
| 81 | struct kobject *kobj, struct bin_attribute *attr, \ | ||
| 82 | char *buf, loff_t off, size_t count) \ | ||
| 83 | { \ | ||
| 84 | return lua_sysfs_read(fp, kobj, buf, off, count, \ | ||
| 85 | LUA_SIZE_ ## THINGY, LUA_COMMAND_ ## THINGY); \ | ||
| 86 | } | ||
| 87 | |||
| 88 | #define LUA_BIN_ATTRIBUTE_RW(thingy, THINGY) \ | ||
| 89 | LUA_SYSFS_W(thingy, THINGY) \ | ||
| 90 | LUA_SYSFS_R(thingy, THINGY) \ | ||
| 91 | static struct bin_attribute lua_ ## thingy ## _attr = { \ | ||
| 92 | .attr = { .name = #thingy, .mode = 0660 }, \ | ||
| 93 | .size = LUA_SIZE_ ## THINGY, \ | ||
| 94 | .read = lua_sysfs_read_ ## thingy, \ | ||
| 95 | .write = lua_sysfs_write_ ## thingy \ | ||
| 96 | }; | ||
| 97 | |||
| 98 | LUA_BIN_ATTRIBUTE_RW(control, CONTROL) | ||
| 99 | |||
| 100 | static int lua_create_sysfs_attributes(struct usb_interface *intf) | ||
| 101 | { | ||
| 102 | return sysfs_create_bin_file(&intf->dev.kobj, &lua_control_attr); | ||
| 103 | } | ||
| 104 | |||
| 105 | static void lua_remove_sysfs_attributes(struct usb_interface *intf) | ||
| 106 | { | ||
| 107 | sysfs_remove_bin_file(&intf->dev.kobj, &lua_control_attr); | ||
| 108 | } | ||
| 109 | |||
| 110 | static int lua_init_lua_device_struct(struct usb_device *usb_dev, | ||
| 111 | struct lua_device *lua) | ||
| 112 | { | ||
| 113 | mutex_init(&lua->lua_lock); | ||
| 114 | |||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | static int lua_init_specials(struct hid_device *hdev) | ||
| 119 | { | ||
| 120 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
| 121 | struct usb_device *usb_dev = interface_to_usbdev(intf); | ||
| 122 | struct lua_device *lua; | ||
| 123 | int retval; | ||
| 124 | |||
| 125 | lua = kzalloc(sizeof(*lua), GFP_KERNEL); | ||
| 126 | if (!lua) { | ||
| 127 | hid_err(hdev, "can't alloc device descriptor\n"); | ||
| 128 | return -ENOMEM; | ||
| 129 | } | ||
| 130 | hid_set_drvdata(hdev, lua); | ||
| 131 | |||
| 132 | retval = lua_init_lua_device_struct(usb_dev, lua); | ||
| 133 | if (retval) { | ||
| 134 | hid_err(hdev, "couldn't init struct lua_device\n"); | ||
| 135 | goto exit; | ||
| 136 | } | ||
| 137 | |||
| 138 | retval = lua_create_sysfs_attributes(intf); | ||
| 139 | if (retval) { | ||
| 140 | hid_err(hdev, "cannot create sysfs files\n"); | ||
| 141 | goto exit; | ||
| 142 | } | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | exit: | ||
| 146 | kfree(lua); | ||
| 147 | return retval; | ||
| 148 | } | ||
| 149 | |||
| 150 | static void lua_remove_specials(struct hid_device *hdev) | ||
| 151 | { | ||
| 152 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
| 153 | struct lua_device *lua; | ||
| 154 | |||
| 155 | lua_remove_sysfs_attributes(intf); | ||
| 156 | |||
| 157 | lua = hid_get_drvdata(hdev); | ||
| 158 | kfree(lua); | ||
| 159 | } | ||
| 160 | |||
| 161 | static int lua_probe(struct hid_device *hdev, | ||
| 162 | const struct hid_device_id *id) | ||
| 163 | { | ||
| 164 | int retval; | ||
| 165 | |||
| 166 | retval = hid_parse(hdev); | ||
| 167 | if (retval) { | ||
| 168 | hid_err(hdev, "parse failed\n"); | ||
| 169 | goto exit; | ||
| 170 | } | ||
| 171 | |||
| 172 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
| 173 | if (retval) { | ||
| 174 | hid_err(hdev, "hw start failed\n"); | ||
| 175 | goto exit; | ||
| 176 | } | ||
| 177 | |||
| 178 | retval = lua_init_specials(hdev); | ||
| 179 | if (retval) { | ||
| 180 | hid_err(hdev, "couldn't install mouse\n"); | ||
| 181 | goto exit_stop; | ||
| 182 | } | ||
| 183 | |||
| 184 | return 0; | ||
| 185 | |||
| 186 | exit_stop: | ||
| 187 | hid_hw_stop(hdev); | ||
| 188 | exit: | ||
| 189 | return retval; | ||
| 190 | } | ||
| 191 | |||
| 192 | static void lua_remove(struct hid_device *hdev) | ||
| 193 | { | ||
| 194 | lua_remove_specials(hdev); | ||
| 195 | hid_hw_stop(hdev); | ||
| 196 | } | ||
| 197 | |||
| 198 | static const struct hid_device_id lua_devices[] = { | ||
| 199 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) }, | ||
| 200 | { } | ||
| 201 | }; | ||
| 202 | |||
| 203 | MODULE_DEVICE_TABLE(hid, lua_devices); | ||
| 204 | |||
| 205 | static struct hid_driver lua_driver = { | ||
| 206 | .name = "lua", | ||
| 207 | .id_table = lua_devices, | ||
| 208 | .probe = lua_probe, | ||
| 209 | .remove = lua_remove | ||
| 210 | }; | ||
| 211 | |||
| 212 | static int __init lua_init(void) | ||
| 213 | { | ||
| 214 | return hid_register_driver(&lua_driver); | ||
| 215 | } | ||
| 216 | |||
| 217 | static void __exit lua_exit(void) | ||
| 218 | { | ||
| 219 | hid_unregister_driver(&lua_driver); | ||
| 220 | } | ||
| 221 | |||
| 222 | module_init(lua_init); | ||
| 223 | module_exit(lua_exit); | ||
| 224 | |||
| 225 | MODULE_AUTHOR("Stefan Achatz"); | ||
| 226 | MODULE_DESCRIPTION("USB Roccat Lua driver"); | ||
| 227 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/hid/hid-roccat-lua.h b/drivers/hid/hid-roccat-lua.h new file mode 100644 index 000000000000..547d77a375d1 --- /dev/null +++ b/drivers/hid/hid-roccat-lua.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | #ifndef __HID_ROCCAT_LUA_H | ||
| 2 | #define __HID_ROCCAT_LUA_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copyright (c) 2012 Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 6 | */ | ||
| 7 | |||
| 8 | /* | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the Free | ||
| 11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 12 | * any later version. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/types.h> | ||
| 16 | |||
| 17 | enum { | ||
| 18 | LUA_SIZE_CONTROL = 8, | ||
| 19 | }; | ||
| 20 | |||
| 21 | enum lua_commands { | ||
| 22 | LUA_COMMAND_CONTROL = 3, | ||
| 23 | }; | ||
| 24 | |||
| 25 | struct lua_device { | ||
| 26 | struct mutex lua_lock; | ||
| 27 | }; | ||
| 28 | |||
| 29 | #endif | ||
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index 1317c177a3e2..d4f1e3bee590 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c | |||
| @@ -66,48 +66,14 @@ static int pyra_get_profile_settings(struct usb_device *usb_dev, | |||
| 66 | if (retval) | 66 | if (retval) |
| 67 | return retval; | 67 | return retval; |
| 68 | return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, | 68 | return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, |
| 69 | buf, sizeof(struct pyra_profile_settings)); | 69 | buf, PYRA_SIZE_PROFILE_SETTINGS); |
| 70 | } | ||
| 71 | |||
| 72 | static int pyra_get_profile_buttons(struct usb_device *usb_dev, | ||
| 73 | struct pyra_profile_buttons *buf, int number) | ||
| 74 | { | ||
| 75 | int retval; | ||
| 76 | retval = pyra_send_control(usb_dev, number, | ||
| 77 | PYRA_CONTROL_REQUEST_PROFILE_BUTTONS); | ||
| 78 | if (retval) | ||
| 79 | return retval; | ||
| 80 | return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, | ||
| 81 | buf, sizeof(struct pyra_profile_buttons)); | ||
| 82 | } | 70 | } |
| 83 | 71 | ||
| 84 | static int pyra_get_settings(struct usb_device *usb_dev, | 72 | static int pyra_get_settings(struct usb_device *usb_dev, |
| 85 | struct pyra_settings *buf) | 73 | struct pyra_settings *buf) |
| 86 | { | 74 | { |
| 87 | return roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS, | 75 | return roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS, |
| 88 | buf, sizeof(struct pyra_settings)); | 76 | buf, PYRA_SIZE_SETTINGS); |
| 89 | } | ||
| 90 | |||
| 91 | static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf) | ||
| 92 | { | ||
| 93 | return roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO, | ||
| 94 | buf, sizeof(struct pyra_info)); | ||
| 95 | } | ||
| 96 | |||
| 97 | static int pyra_set_profile_settings(struct usb_device *usb_dev, | ||
| 98 | struct pyra_profile_settings const *settings) | ||
| 99 | { | ||
| 100 | return roccat_common2_send_with_status(usb_dev, | ||
| 101 | PYRA_COMMAND_PROFILE_SETTINGS, settings, | ||
| 102 | sizeof(struct pyra_profile_settings)); | ||
| 103 | } | ||
| 104 | |||
| 105 | static int pyra_set_profile_buttons(struct usb_device *usb_dev, | ||
| 106 | struct pyra_profile_buttons const *buttons) | ||
| 107 | { | ||
| 108 | return roccat_common2_send_with_status(usb_dev, | ||
| 109 | PYRA_COMMAND_PROFILE_BUTTONS, buttons, | ||
| 110 | sizeof(struct pyra_profile_buttons)); | ||
| 111 | } | 77 | } |
| 112 | 78 | ||
| 113 | static int pyra_set_settings(struct usb_device *usb_dev, | 79 | static int pyra_set_settings(struct usb_device *usb_dev, |
| @@ -115,146 +81,144 @@ static int pyra_set_settings(struct usb_device *usb_dev, | |||
| 115 | { | 81 | { |
| 116 | return roccat_common2_send_with_status(usb_dev, | 82 | return roccat_common2_send_with_status(usb_dev, |
| 117 | PYRA_COMMAND_SETTINGS, settings, | 83 | PYRA_COMMAND_SETTINGS, settings, |
| 118 | sizeof(struct pyra_settings)); | 84 | PYRA_SIZE_SETTINGS); |
| 119 | } | 85 | } |
| 120 | 86 | ||
| 121 | static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, | 87 | static ssize_t pyra_sysfs_read(struct file *fp, struct kobject *kobj, |
| 122 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 88 | char *buf, loff_t off, size_t count, |
| 123 | loff_t off, size_t count) | 89 | size_t real_size, uint command) |
| 124 | { | 90 | { |
| 125 | struct device *dev = | 91 | struct device *dev = |
| 126 | container_of(kobj, struct device, kobj)->parent->parent; | 92 | container_of(kobj, struct device, kobj)->parent->parent; |
| 127 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | 93 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); |
| 94 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 95 | int retval; | ||
| 128 | 96 | ||
| 129 | if (off >= sizeof(struct pyra_profile_settings)) | 97 | if (off >= real_size) |
| 130 | return 0; | 98 | return 0; |
| 131 | 99 | ||
| 132 | if (off + count > sizeof(struct pyra_profile_settings)) | 100 | if (off != 0 || count != real_size) |
| 133 | count = sizeof(struct pyra_profile_settings) - off; | 101 | return -EINVAL; |
| 134 | 102 | ||
| 135 | mutex_lock(&pyra->pyra_lock); | 103 | mutex_lock(&pyra->pyra_lock); |
| 136 | memcpy(buf, ((char const *)&pyra->profile_settings[*(uint *)(attr->private)]) + off, | 104 | retval = roccat_common2_receive(usb_dev, command, buf, real_size); |
| 137 | count); | ||
| 138 | mutex_unlock(&pyra->pyra_lock); | 105 | mutex_unlock(&pyra->pyra_lock); |
| 139 | 106 | ||
| 140 | return count; | 107 | if (retval) |
| 108 | return retval; | ||
| 109 | |||
| 110 | return real_size; | ||
| 141 | } | 111 | } |
| 142 | 112 | ||
| 143 | static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, | 113 | static ssize_t pyra_sysfs_write(struct file *fp, struct kobject *kobj, |
| 144 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 114 | void const *buf, loff_t off, size_t count, |
| 145 | loff_t off, size_t count) | 115 | size_t real_size, uint command) |
| 146 | { | 116 | { |
| 147 | struct device *dev = | 117 | struct device *dev = |
| 148 | container_of(kobj, struct device, kobj)->parent->parent; | 118 | container_of(kobj, struct device, kobj)->parent->parent; |
| 149 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | 119 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); |
| 120 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 121 | int retval; | ||
| 150 | 122 | ||
| 151 | if (off >= sizeof(struct pyra_profile_buttons)) | 123 | if (off != 0 || count != real_size) |
| 152 | return 0; | 124 | return -EINVAL; |
| 153 | |||
| 154 | if (off + count > sizeof(struct pyra_profile_buttons)) | ||
| 155 | count = sizeof(struct pyra_profile_buttons) - off; | ||
| 156 | 125 | ||
| 157 | mutex_lock(&pyra->pyra_lock); | 126 | mutex_lock(&pyra->pyra_lock); |
| 158 | memcpy(buf, ((char const *)&pyra->profile_buttons[*(uint *)(attr->private)]) + off, | 127 | retval = roccat_common2_send_with_status(usb_dev, command, (void *)buf, real_size); |
| 159 | count); | ||
| 160 | mutex_unlock(&pyra->pyra_lock); | 128 | mutex_unlock(&pyra->pyra_lock); |
| 161 | 129 | ||
| 162 | return count; | 130 | if (retval) |
| 131 | return retval; | ||
| 132 | |||
| 133 | return real_size; | ||
| 163 | } | 134 | } |
| 164 | 135 | ||
| 165 | static ssize_t pyra_sysfs_write_profile_settings(struct file *fp, | 136 | #define PYRA_SYSFS_W(thingy, THINGY) \ |
| 166 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 137 | static ssize_t pyra_sysfs_write_ ## thingy(struct file *fp, \ |
| 167 | loff_t off, size_t count) | 138 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ |
| 168 | { | 139 | loff_t off, size_t count) \ |
| 169 | struct device *dev = | 140 | { \ |
| 170 | container_of(kobj, struct device, kobj)->parent->parent; | 141 | return pyra_sysfs_write(fp, kobj, buf, off, count, \ |
| 171 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | 142 | PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \ |
| 172 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 143 | } |
| 173 | int retval = 0; | ||
| 174 | int difference; | ||
| 175 | int profile_number; | ||
| 176 | struct pyra_profile_settings *profile_settings; | ||
| 177 | 144 | ||
| 178 | if (off != 0 || count != sizeof(struct pyra_profile_settings)) | 145 | #define PYRA_SYSFS_R(thingy, THINGY) \ |
| 179 | return -EINVAL; | 146 | static ssize_t pyra_sysfs_read_ ## thingy(struct file *fp, \ |
| 147 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ | ||
| 148 | loff_t off, size_t count) \ | ||
| 149 | { \ | ||
| 150 | return pyra_sysfs_read(fp, kobj, buf, off, count, \ | ||
| 151 | PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \ | ||
| 152 | } | ||
| 180 | 153 | ||
| 181 | profile_number = ((struct pyra_profile_settings const *)buf)->number; | 154 | #define PYRA_SYSFS_RW(thingy, THINGY) \ |
| 182 | profile_settings = &pyra->profile_settings[profile_number]; | 155 | PYRA_SYSFS_W(thingy, THINGY) \ |
| 156 | PYRA_SYSFS_R(thingy, THINGY) | ||
| 183 | 157 | ||
| 184 | mutex_lock(&pyra->pyra_lock); | 158 | #define PYRA_BIN_ATTRIBUTE_RW(thingy, THINGY) \ |
| 185 | difference = memcmp(buf, profile_settings, | 159 | { \ |
| 186 | sizeof(struct pyra_profile_settings)); | 160 | .attr = { .name = #thingy, .mode = 0660 }, \ |
| 187 | if (difference) { | 161 | .size = PYRA_SIZE_ ## THINGY, \ |
| 188 | retval = pyra_set_profile_settings(usb_dev, | 162 | .read = pyra_sysfs_read_ ## thingy, \ |
| 189 | (struct pyra_profile_settings const *)buf); | 163 | .write = pyra_sysfs_write_ ## thingy \ |
| 190 | if (!retval) | 164 | } |
| 191 | memcpy(profile_settings, buf, | ||
| 192 | sizeof(struct pyra_profile_settings)); | ||
| 193 | } | ||
| 194 | mutex_unlock(&pyra->pyra_lock); | ||
| 195 | 165 | ||
| 196 | if (retval) | 166 | #define PYRA_BIN_ATTRIBUTE_R(thingy, THINGY) \ |
| 197 | return retval; | 167 | { \ |
| 168 | .attr = { .name = #thingy, .mode = 0440 }, \ | ||
| 169 | .size = PYRA_SIZE_ ## THINGY, \ | ||
| 170 | .read = pyra_sysfs_read_ ## thingy, \ | ||
| 171 | } | ||
| 198 | 172 | ||
| 199 | return sizeof(struct pyra_profile_settings); | 173 | #define PYRA_BIN_ATTRIBUTE_W(thingy, THINGY) \ |
| 174 | { \ | ||
| 175 | .attr = { .name = #thingy, .mode = 0220 }, \ | ||
| 176 | .size = PYRA_SIZE_ ## THINGY, \ | ||
| 177 | .write = pyra_sysfs_write_ ## thingy \ | ||
| 200 | } | 178 | } |
| 201 | 179 | ||
| 202 | static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp, | 180 | PYRA_SYSFS_W(control, CONTROL) |
| 181 | PYRA_SYSFS_RW(info, INFO) | ||
| 182 | PYRA_SYSFS_RW(profile_settings, PROFILE_SETTINGS) | ||
| 183 | PYRA_SYSFS_RW(profile_buttons, PROFILE_BUTTONS) | ||
| 184 | PYRA_SYSFS_R(settings, SETTINGS) | ||
| 185 | |||
| 186 | static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, | ||
| 203 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 187 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
| 204 | loff_t off, size_t count) | 188 | loff_t off, size_t count) |
| 205 | { | 189 | { |
| 206 | struct device *dev = | 190 | struct device *dev = |
| 207 | container_of(kobj, struct device, kobj)->parent->parent; | 191 | container_of(kobj, struct device, kobj)->parent->parent; |
| 208 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 209 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 192 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 210 | int retval = 0; | 193 | ssize_t retval; |
| 211 | int difference; | ||
| 212 | int profile_number; | ||
| 213 | struct pyra_profile_buttons *profile_buttons; | ||
| 214 | |||
| 215 | if (off != 0 || count != sizeof(struct pyra_profile_buttons)) | ||
| 216 | return -EINVAL; | ||
| 217 | |||
| 218 | profile_number = ((struct pyra_profile_buttons const *)buf)->number; | ||
| 219 | profile_buttons = &pyra->profile_buttons[profile_number]; | ||
| 220 | |||
| 221 | mutex_lock(&pyra->pyra_lock); | ||
| 222 | difference = memcmp(buf, profile_buttons, | ||
| 223 | sizeof(struct pyra_profile_buttons)); | ||
| 224 | if (difference) { | ||
| 225 | retval = pyra_set_profile_buttons(usb_dev, | ||
| 226 | (struct pyra_profile_buttons const *)buf); | ||
| 227 | if (!retval) | ||
| 228 | memcpy(profile_buttons, buf, | ||
| 229 | sizeof(struct pyra_profile_buttons)); | ||
| 230 | } | ||
| 231 | mutex_unlock(&pyra->pyra_lock); | ||
| 232 | 194 | ||
| 195 | retval = pyra_send_control(usb_dev, *(uint *)(attr->private), | ||
| 196 | PYRA_CONTROL_REQUEST_PROFILE_SETTINGS); | ||
| 233 | if (retval) | 197 | if (retval) |
| 234 | return retval; | 198 | return retval; |
| 235 | 199 | ||
| 236 | return sizeof(struct pyra_profile_buttons); | 200 | return pyra_sysfs_read(fp, kobj, buf, off, count, |
| 201 | PYRA_SIZE_PROFILE_SETTINGS, | ||
| 202 | PYRA_COMMAND_PROFILE_SETTINGS); | ||
| 237 | } | 203 | } |
| 238 | 204 | ||
| 239 | static ssize_t pyra_sysfs_read_settings(struct file *fp, | 205 | static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, |
| 240 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 206 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
| 241 | loff_t off, size_t count) | 207 | loff_t off, size_t count) |
| 242 | { | 208 | { |
| 243 | struct device *dev = | 209 | struct device *dev = |
| 244 | container_of(kobj, struct device, kobj)->parent->parent; | 210 | container_of(kobj, struct device, kobj)->parent->parent; |
| 245 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | 211 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 246 | 212 | ssize_t retval; | |
| 247 | if (off >= sizeof(struct pyra_settings)) | ||
| 248 | return 0; | ||
| 249 | |||
| 250 | if (off + count > sizeof(struct pyra_settings)) | ||
| 251 | count = sizeof(struct pyra_settings) - off; | ||
| 252 | 213 | ||
| 253 | mutex_lock(&pyra->pyra_lock); | 214 | retval = pyra_send_control(usb_dev, *(uint *)(attr->private), |
| 254 | memcpy(buf, ((char const *)&pyra->settings) + off, count); | 215 | PYRA_CONTROL_REQUEST_PROFILE_BUTTONS); |
| 255 | mutex_unlock(&pyra->pyra_lock); | 216 | if (retval) |
| 217 | return retval; | ||
| 256 | 218 | ||
| 257 | return count; | 219 | return pyra_sysfs_read(fp, kobj, buf, off, count, |
| 220 | PYRA_SIZE_PROFILE_BUTTONS, | ||
| 221 | PYRA_COMMAND_PROFILE_BUTTONS); | ||
| 258 | } | 222 | } |
| 259 | 223 | ||
| 260 | static ssize_t pyra_sysfs_write_settings(struct file *fp, | 224 | static ssize_t pyra_sysfs_write_settings(struct file *fp, |
| @@ -266,35 +230,32 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp, | |||
| 266 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | 230 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); |
| 267 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 231 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 268 | int retval = 0; | 232 | int retval = 0; |
| 269 | int difference; | ||
| 270 | struct pyra_roccat_report roccat_report; | 233 | struct pyra_roccat_report roccat_report; |
| 234 | struct pyra_settings const *settings; | ||
| 271 | 235 | ||
| 272 | if (off != 0 || count != sizeof(struct pyra_settings)) | 236 | if (off != 0 || count != PYRA_SIZE_SETTINGS) |
| 273 | return -EINVAL; | 237 | return -EINVAL; |
| 274 | 238 | ||
| 275 | mutex_lock(&pyra->pyra_lock); | 239 | mutex_lock(&pyra->pyra_lock); |
| 276 | difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings)); | ||
| 277 | if (difference) { | ||
| 278 | retval = pyra_set_settings(usb_dev, | ||
| 279 | (struct pyra_settings const *)buf); | ||
| 280 | if (retval) { | ||
| 281 | mutex_unlock(&pyra->pyra_lock); | ||
| 282 | return retval; | ||
| 283 | } | ||
| 284 | |||
| 285 | memcpy(&pyra->settings, buf, | ||
| 286 | sizeof(struct pyra_settings)); | ||
| 287 | 240 | ||
| 288 | profile_activated(pyra, pyra->settings.startup_profile); | 241 | settings = (struct pyra_settings const *)buf; |
| 289 | 242 | ||
| 290 | roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2; | 243 | retval = pyra_set_settings(usb_dev, settings); |
| 291 | roccat_report.value = pyra->settings.startup_profile + 1; | 244 | if (retval) { |
| 292 | roccat_report.key = 0; | 245 | mutex_unlock(&pyra->pyra_lock); |
| 293 | roccat_report_event(pyra->chrdev_minor, | 246 | return retval; |
| 294 | (uint8_t const *)&roccat_report); | ||
| 295 | } | 247 | } |
| 248 | |||
| 249 | profile_activated(pyra, settings->startup_profile); | ||
| 250 | |||
| 251 | roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2; | ||
| 252 | roccat_report.value = settings->startup_profile + 1; | ||
| 253 | roccat_report.key = 0; | ||
| 254 | roccat_report_event(pyra->chrdev_minor, | ||
| 255 | (uint8_t const *)&roccat_report); | ||
| 256 | |||
| 296 | mutex_unlock(&pyra->pyra_lock); | 257 | mutex_unlock(&pyra->pyra_lock); |
| 297 | return sizeof(struct pyra_settings); | 258 | return PYRA_SIZE_SETTINGS; |
| 298 | } | 259 | } |
| 299 | 260 | ||
| 300 | 261 | ||
| @@ -311,23 +272,34 @@ static ssize_t pyra_sysfs_show_actual_profile(struct device *dev, | |||
| 311 | { | 272 | { |
| 312 | struct pyra_device *pyra = | 273 | struct pyra_device *pyra = |
| 313 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 274 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
| 314 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile); | 275 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 276 | struct pyra_settings settings; | ||
| 277 | |||
| 278 | mutex_lock(&pyra->pyra_lock); | ||
| 279 | roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS, | ||
| 280 | &settings, PYRA_SIZE_SETTINGS); | ||
| 281 | mutex_unlock(&pyra->pyra_lock); | ||
| 282 | |||
| 283 | return snprintf(buf, PAGE_SIZE, "%d\n", settings.startup_profile); | ||
| 315 | } | 284 | } |
| 316 | 285 | ||
| 317 | static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, | 286 | static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, |
| 318 | struct device_attribute *attr, char *buf) | 287 | struct device_attribute *attr, char *buf) |
| 319 | { | 288 | { |
| 320 | struct pyra_device *pyra = | 289 | struct pyra_device *pyra; |
| 321 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 290 | struct usb_device *usb_dev; |
| 322 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version); | 291 | struct pyra_info info; |
| 323 | } | ||
| 324 | 292 | ||
| 325 | static ssize_t pyra_sysfs_show_startup_profile(struct device *dev, | 293 | dev = dev->parent->parent; |
| 326 | struct device_attribute *attr, char *buf) | 294 | pyra = hid_get_drvdata(dev_get_drvdata(dev)); |
| 327 | { | 295 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 328 | struct pyra_device *pyra = | 296 | |
| 329 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 297 | mutex_lock(&pyra->pyra_lock); |
| 330 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile); | 298 | roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO, |
| 299 | &info, PYRA_SIZE_INFO); | ||
| 300 | mutex_unlock(&pyra->pyra_lock); | ||
| 301 | |||
| 302 | return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); | ||
| 331 | } | 303 | } |
| 332 | 304 | ||
| 333 | static struct device_attribute pyra_attributes[] = { | 305 | static struct device_attribute pyra_attributes[] = { |
| @@ -336,105 +308,88 @@ static struct device_attribute pyra_attributes[] = { | |||
| 336 | __ATTR(firmware_version, 0440, | 308 | __ATTR(firmware_version, 0440, |
| 337 | pyra_sysfs_show_firmware_version, NULL), | 309 | pyra_sysfs_show_firmware_version, NULL), |
| 338 | __ATTR(startup_profile, 0440, | 310 | __ATTR(startup_profile, 0440, |
| 339 | pyra_sysfs_show_startup_profile, NULL), | 311 | pyra_sysfs_show_actual_profile, NULL), |
| 340 | __ATTR_NULL | 312 | __ATTR_NULL |
| 341 | }; | 313 | }; |
| 342 | 314 | ||
| 343 | static struct bin_attribute pyra_bin_attributes[] = { | 315 | static struct bin_attribute pyra_bin_attributes[] = { |
| 344 | { | 316 | PYRA_BIN_ATTRIBUTE_W(control, CONTROL), |
| 345 | .attr = { .name = "profile_settings", .mode = 0220 }, | 317 | PYRA_BIN_ATTRIBUTE_RW(info, INFO), |
| 346 | .size = sizeof(struct pyra_profile_settings), | 318 | PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS), |
| 347 | .write = pyra_sysfs_write_profile_settings | 319 | PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS), |
| 348 | }, | 320 | PYRA_BIN_ATTRIBUTE_RW(settings, SETTINGS), |
| 349 | { | 321 | { |
| 350 | .attr = { .name = "profile1_settings", .mode = 0440 }, | 322 | .attr = { .name = "profile1_settings", .mode = 0440 }, |
| 351 | .size = sizeof(struct pyra_profile_settings), | 323 | .size = PYRA_SIZE_PROFILE_SETTINGS, |
| 352 | .read = pyra_sysfs_read_profilex_settings, | 324 | .read = pyra_sysfs_read_profilex_settings, |
| 353 | .private = &profile_numbers[0] | 325 | .private = &profile_numbers[0] |
| 354 | }, | 326 | }, |
| 355 | { | 327 | { |
| 356 | .attr = { .name = "profile2_settings", .mode = 0440 }, | 328 | .attr = { .name = "profile2_settings", .mode = 0440 }, |
| 357 | .size = sizeof(struct pyra_profile_settings), | 329 | .size = PYRA_SIZE_PROFILE_SETTINGS, |
| 358 | .read = pyra_sysfs_read_profilex_settings, | 330 | .read = pyra_sysfs_read_profilex_settings, |
| 359 | .private = &profile_numbers[1] | 331 | .private = &profile_numbers[1] |
| 360 | }, | 332 | }, |
| 361 | { | 333 | { |
| 362 | .attr = { .name = "profile3_settings", .mode = 0440 }, | 334 | .attr = { .name = "profile3_settings", .mode = 0440 }, |
| 363 | .size = sizeof(struct pyra_profile_settings), | 335 | .size = PYRA_SIZE_PROFILE_SETTINGS, |
| 364 | .read = pyra_sysfs_read_profilex_settings, | 336 | .read = pyra_sysfs_read_profilex_settings, |
| 365 | .private = &profile_numbers[2] | 337 | .private = &profile_numbers[2] |
| 366 | }, | 338 | }, |
| 367 | { | 339 | { |
| 368 | .attr = { .name = "profile4_settings", .mode = 0440 }, | 340 | .attr = { .name = "profile4_settings", .mode = 0440 }, |
| 369 | .size = sizeof(struct pyra_profile_settings), | 341 | .size = PYRA_SIZE_PROFILE_SETTINGS, |
| 370 | .read = pyra_sysfs_read_profilex_settings, | 342 | .read = pyra_sysfs_read_profilex_settings, |
| 371 | .private = &profile_numbers[3] | 343 | .private = &profile_numbers[3] |
| 372 | }, | 344 | }, |
| 373 | { | 345 | { |
| 374 | .attr = { .name = "profile5_settings", .mode = 0440 }, | 346 | .attr = { .name = "profile5_settings", .mode = 0440 }, |
| 375 | .size = sizeof(struct pyra_profile_settings), | 347 | .size = PYRA_SIZE_PROFILE_SETTINGS, |
| 376 | .read = pyra_sysfs_read_profilex_settings, | 348 | .read = pyra_sysfs_read_profilex_settings, |
| 377 | .private = &profile_numbers[4] | 349 | .private = &profile_numbers[4] |
| 378 | }, | 350 | }, |
| 379 | { | 351 | { |
| 380 | .attr = { .name = "profile_buttons", .mode = 0220 }, | ||
| 381 | .size = sizeof(struct pyra_profile_buttons), | ||
| 382 | .write = pyra_sysfs_write_profile_buttons | ||
| 383 | }, | ||
| 384 | { | ||
| 385 | .attr = { .name = "profile1_buttons", .mode = 0440 }, | 352 | .attr = { .name = "profile1_buttons", .mode = 0440 }, |
| 386 | .size = sizeof(struct pyra_profile_buttons), | 353 | .size = PYRA_SIZE_PROFILE_BUTTONS, |
| 387 | .read = pyra_sysfs_read_profilex_buttons, | 354 | .read = pyra_sysfs_read_profilex_buttons, |
| 388 | .private = &profile_numbers[0] | 355 | .private = &profile_numbers[0] |
| 389 | }, | 356 | }, |
| 390 | { | 357 | { |
| 391 | .attr = { .name = "profile2_buttons", .mode = 0440 }, | 358 | .attr = { .name = "profile2_buttons", .mode = 0440 }, |
| 392 | .size = sizeof(struct pyra_profile_buttons), | 359 | .size = PYRA_SIZE_PROFILE_BUTTONS, |
| 393 | .read = pyra_sysfs_read_profilex_buttons, | 360 | .read = pyra_sysfs_read_profilex_buttons, |
| 394 | .private = &profile_numbers[1] | 361 | .private = &profile_numbers[1] |
| 395 | }, | 362 | }, |
| 396 | { | 363 | { |
| 397 | .attr = { .name = "profile3_buttons", .mode = 0440 }, | 364 | .attr = { .name = "profile3_buttons", .mode = 0440 }, |
| 398 | .size = sizeof(struct pyra_profile_buttons), | 365 | .size = PYRA_SIZE_PROFILE_BUTTONS, |
| 399 | .read = pyra_sysfs_read_profilex_buttons, | 366 | .read = pyra_sysfs_read_profilex_buttons, |
| 400 | .private = &profile_numbers[2] | 367 | .private = &profile_numbers[2] |
| 401 | }, | 368 | }, |
| 402 | { | 369 | { |
| 403 | .attr = { .name = "profile4_buttons", .mode = 0440 }, | 370 | .attr = { .name = "profile4_buttons", .mode = 0440 }, |
| 404 | .size = sizeof(struct pyra_profile_buttons), | 371 | .size = PYRA_SIZE_PROFILE_BUTTONS, |
| 405 | .read = pyra_sysfs_read_profilex_buttons, | 372 | .read = pyra_sysfs_read_profilex_buttons, |
| 406 | .private = &profile_numbers[3] | 373 | .private = &profile_numbers[3] |
| 407 | }, | 374 | }, |
| 408 | { | 375 | { |
| 409 | .attr = { .name = "profile5_buttons", .mode = 0440 }, | 376 | .attr = { .name = "profile5_buttons", .mode = 0440 }, |
| 410 | .size = sizeof(struct pyra_profile_buttons), | 377 | .size = PYRA_SIZE_PROFILE_BUTTONS, |
| 411 | .read = pyra_sysfs_read_profilex_buttons, | 378 | .read = pyra_sysfs_read_profilex_buttons, |
| 412 | .private = &profile_numbers[4] | 379 | .private = &profile_numbers[4] |
| 413 | }, | 380 | }, |
| 414 | { | ||
| 415 | .attr = { .name = "settings", .mode = 0660 }, | ||
| 416 | .size = sizeof(struct pyra_settings), | ||
| 417 | .read = pyra_sysfs_read_settings, | ||
| 418 | .write = pyra_sysfs_write_settings | ||
| 419 | }, | ||
| 420 | __ATTR_NULL | 381 | __ATTR_NULL |
| 421 | }; | 382 | }; |
| 422 | 383 | ||
| 423 | static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, | 384 | static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, |
| 424 | struct pyra_device *pyra) | 385 | struct pyra_device *pyra) |
| 425 | { | 386 | { |
| 426 | struct pyra_info info; | 387 | struct pyra_settings settings; |
| 427 | int retval, i; | 388 | int retval, i; |
| 428 | 389 | ||
| 429 | mutex_init(&pyra->pyra_lock); | 390 | mutex_init(&pyra->pyra_lock); |
| 430 | 391 | ||
| 431 | retval = pyra_get_info(usb_dev, &info); | 392 | retval = pyra_get_settings(usb_dev, &settings); |
| 432 | if (retval) | ||
| 433 | return retval; | ||
| 434 | |||
| 435 | pyra->firmware_version = info.firmware_version; | ||
| 436 | |||
| 437 | retval = pyra_get_settings(usb_dev, &pyra->settings); | ||
| 438 | if (retval) | 393 | if (retval) |
| 439 | return retval; | 394 | return retval; |
| 440 | 395 | ||
| @@ -443,14 +398,9 @@ static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, | |||
| 443 | &pyra->profile_settings[i], i); | 398 | &pyra->profile_settings[i], i); |
| 444 | if (retval) | 399 | if (retval) |
| 445 | return retval; | 400 | return retval; |
| 446 | |||
| 447 | retval = pyra_get_profile_buttons(usb_dev, | ||
| 448 | &pyra->profile_buttons[i], i); | ||
| 449 | if (retval) | ||
| 450 | return retval; | ||
| 451 | } | 401 | } |
| 452 | 402 | ||
| 453 | profile_activated(pyra, pyra->settings.startup_profile); | 403 | profile_activated(pyra, settings.startup_profile); |
| 454 | 404 | ||
| 455 | return 0; | 405 | return 0; |
| 456 | } | 406 | } |
diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h index eada7830fa99..beedcf001ceb 100644 --- a/drivers/hid/hid-roccat-pyra.h +++ b/drivers/hid/hid-roccat-pyra.h | |||
| @@ -14,11 +14,13 @@ | |||
| 14 | 14 | ||
| 15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 16 | 16 | ||
| 17 | struct pyra_b { | 17 | enum { |
| 18 | uint8_t command; /* PYRA_COMMAND_B */ | 18 | PYRA_SIZE_CONTROL = 0x03, |
| 19 | uint8_t size; /* always 3 */ | 19 | PYRA_SIZE_INFO = 0x06, |
| 20 | uint8_t unknown; /* 1 */ | 20 | PYRA_SIZE_PROFILE_SETTINGS = 0x0d, |
| 21 | } __attribute__ ((__packed__)); | 21 | PYRA_SIZE_PROFILE_BUTTONS = 0x13, |
| 22 | PYRA_SIZE_SETTINGS = 0x03, | ||
| 23 | }; | ||
| 22 | 24 | ||
| 23 | enum pyra_control_requests { | 25 | enum pyra_control_requests { |
| 24 | PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, | 26 | PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, |
| @@ -46,14 +48,6 @@ struct pyra_profile_settings { | |||
| 46 | uint16_t checksum; /* byte sum */ | 48 | uint16_t checksum; /* byte sum */ |
| 47 | } __attribute__ ((__packed__)); | 49 | } __attribute__ ((__packed__)); |
| 48 | 50 | ||
| 49 | struct pyra_profile_buttons { | ||
| 50 | uint8_t command; /* PYRA_COMMAND_PROFILE_BUTTONS */ | ||
| 51 | uint8_t size; /* always 0x13 */ | ||
| 52 | uint8_t number; /* Range 0-4 */ | ||
| 53 | uint8_t buttons[14]; | ||
| 54 | uint16_t checksum; /* byte sum */ | ||
| 55 | } __attribute__ ((__packed__)); | ||
| 56 | |||
| 57 | struct pyra_info { | 51 | struct pyra_info { |
| 58 | uint8_t command; /* PYRA_COMMAND_INFO */ | 52 | uint8_t command; /* PYRA_COMMAND_INFO */ |
| 59 | uint8_t size; /* always 6 */ | 53 | uint8_t size; /* always 6 */ |
| @@ -64,6 +58,7 @@ struct pyra_info { | |||
| 64 | } __attribute__ ((__packed__)); | 58 | } __attribute__ ((__packed__)); |
| 65 | 59 | ||
| 66 | enum pyra_commands { | 60 | enum pyra_commands { |
| 61 | PYRA_COMMAND_CONTROL = 0x4, | ||
| 67 | PYRA_COMMAND_SETTINGS = 0x5, | 62 | PYRA_COMMAND_SETTINGS = 0x5, |
| 68 | PYRA_COMMAND_PROFILE_SETTINGS = 0x6, | 63 | PYRA_COMMAND_PROFILE_SETTINGS = 0x6, |
| 69 | PYRA_COMMAND_PROFILE_BUTTONS = 0x7, | 64 | PYRA_COMMAND_PROFILE_BUTTONS = 0x7, |
| @@ -148,13 +143,10 @@ struct pyra_roccat_report { | |||
| 148 | struct pyra_device { | 143 | struct pyra_device { |
| 149 | int actual_profile; | 144 | int actual_profile; |
| 150 | int actual_cpi; | 145 | int actual_cpi; |
| 151 | int firmware_version; | ||
| 152 | int roccat_claimed; | 146 | int roccat_claimed; |
| 153 | int chrdev_minor; | 147 | int chrdev_minor; |
| 154 | struct mutex pyra_lock; | 148 | struct mutex pyra_lock; |
| 155 | struct pyra_settings settings; | ||
| 156 | struct pyra_profile_settings profile_settings[5]; | 149 | struct pyra_profile_settings profile_settings[5]; |
| 157 | struct pyra_profile_buttons profile_buttons[5]; | ||
| 158 | }; | 150 | }; |
| 159 | 151 | ||
| 160 | #endif | 152 | #endif |
diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c index 014afba407e0..31747a29c093 100644 --- a/drivers/hid/hid-roccat-savu.c +++ b/drivers/hid/hid-roccat-savu.c | |||
| @@ -120,7 +120,7 @@ SAVU_SYSFS_RW(profile, PROFILE) | |||
| 120 | SAVU_SYSFS_RW(general, GENERAL) | 120 | SAVU_SYSFS_RW(general, GENERAL) |
| 121 | SAVU_SYSFS_RW(buttons, BUTTONS) | 121 | SAVU_SYSFS_RW(buttons, BUTTONS) |
| 122 | SAVU_SYSFS_RW(macro, MACRO) | 122 | SAVU_SYSFS_RW(macro, MACRO) |
| 123 | SAVU_SYSFS_R(info, INFO) | 123 | SAVU_SYSFS_RW(info, INFO) |
| 124 | SAVU_SYSFS_RW(sensor, SENSOR) | 124 | SAVU_SYSFS_RW(sensor, SENSOR) |
| 125 | 125 | ||
| 126 | static struct bin_attribute savu_bin_attributes[] = { | 126 | static struct bin_attribute savu_bin_attributes[] = { |
| @@ -129,7 +129,7 @@ static struct bin_attribute savu_bin_attributes[] = { | |||
| 129 | SAVU_BIN_ATTRIBUTE_RW(general, GENERAL), | 129 | SAVU_BIN_ATTRIBUTE_RW(general, GENERAL), |
| 130 | SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS), | 130 | SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS), |
| 131 | SAVU_BIN_ATTRIBUTE_RW(macro, MACRO), | 131 | SAVU_BIN_ATTRIBUTE_RW(macro, MACRO), |
| 132 | SAVU_BIN_ATTRIBUTE_R(info, INFO), | 132 | SAVU_BIN_ATTRIBUTE_RW(info, INFO), |
| 133 | SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR), | 133 | SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR), |
| 134 | __ATTR_NULL | 134 | __ATTR_NULL |
| 135 | }; | 135 | }; |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index d9d73e9163eb..0bc58bd8d4f5 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
| @@ -82,23 +82,6 @@ struct hid_sensor_hub_callbacks_list { | |||
| 82 | void *priv; | 82 | void *priv; |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | static int sensor_hub_check_for_sensor_page(struct hid_device *hdev) | ||
| 86 | { | ||
| 87 | int i; | ||
| 88 | int ret = -EINVAL; | ||
| 89 | |||
| 90 | for (i = 0; i < hdev->maxcollection; i++) { | ||
| 91 | struct hid_collection *col = &hdev->collection[i]; | ||
| 92 | if (col->type == HID_COLLECTION_PHYSICAL && | ||
| 93 | (col->usage & HID_USAGE_PAGE) == HID_UP_SENSOR) { | ||
| 94 | ret = 0; | ||
| 95 | break; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | return ret; | ||
| 100 | } | ||
| 101 | |||
| 102 | static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev, | 85 | static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev, |
| 103 | int dir) | 86 | int dir) |
| 104 | { | 87 | { |
| @@ -437,9 +420,6 @@ static int sensor_hub_raw_event(struct hid_device *hdev, | |||
| 437 | ptr = raw_data; | 420 | ptr = raw_data; |
| 438 | ptr++; /*Skip report id*/ | 421 | ptr++; /*Skip report id*/ |
| 439 | 422 | ||
| 440 | if (!report) | ||
| 441 | goto err_report; | ||
| 442 | |||
| 443 | spin_lock_irqsave(&pdata->lock, flags); | 423 | spin_lock_irqsave(&pdata->lock, flags); |
| 444 | 424 | ||
| 445 | for (i = 0; i < report->maxfield; ++i) { | 425 | for (i = 0; i < report->maxfield; ++i) { |
| @@ -485,7 +465,6 @@ static int sensor_hub_raw_event(struct hid_device *hdev, | |||
| 485 | callback->pdev); | 465 | callback->pdev); |
| 486 | spin_unlock_irqrestore(&pdata->lock, flags); | 466 | spin_unlock_irqrestore(&pdata->lock, flags); |
| 487 | 467 | ||
| 488 | err_report: | ||
| 489 | return 1; | 468 | return 1; |
| 490 | } | 469 | } |
| 491 | 470 | ||
| @@ -524,10 +503,6 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
| 524 | hid_err(hdev, "parse failed\n"); | 503 | hid_err(hdev, "parse failed\n"); |
| 525 | goto err_free; | 504 | goto err_free; |
| 526 | } | 505 | } |
| 527 | if (sensor_hub_check_for_sensor_page(hdev) < 0) { | ||
| 528 | hid_err(hdev, "sensor page not found\n"); | ||
| 529 | goto err_free; | ||
| 530 | } | ||
| 531 | INIT_LIST_HEAD(&hdev->inputs); | 506 | INIT_LIST_HEAD(&hdev->inputs); |
| 532 | 507 | ||
| 533 | ret = hid_hw_start(hdev, 0); | 508 | ret = hid_hw_start(hdev, 0); |
| @@ -630,16 +605,7 @@ static void sensor_hub_remove(struct hid_device *hdev) | |||
| 630 | } | 605 | } |
| 631 | 606 | ||
| 632 | static const struct hid_device_id sensor_hub_devices[] = { | 607 | static const struct hid_device_id sensor_hub_devices[] = { |
| 633 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, | 608 | { HID_DEVICE(BUS_USB, HID_GROUP_SENSOR_HUB, HID_ANY_ID, HID_ANY_ID) }, |
| 634 | USB_DEVICE_ID_SENSOR_HUB_1020) }, | ||
| 635 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, | ||
| 636 | USB_DEVICE_ID_SENSOR_HUB_1020) }, | ||
| 637 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, | ||
| 638 | USB_DEVICE_ID_SENSOR_HUB_09FA) }, | ||
| 639 | { HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, | ||
| 640 | USB_DEVICE_ID_SENSOR_HUB_09FA) }, | ||
| 641 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, | ||
| 642 | USB_DEVICE_ID_SENSOR_HUB_7014) }, | ||
| 643 | { } | 609 | { } |
| 644 | }; | 610 | }; |
| 645 | MODULE_DEVICE_TABLE(hid, sensor_hub_devices); | 611 | MODULE_DEVICE_TABLE(hid, sensor_hub_devices); |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 7c47fc3f7b2b..413a73187d33 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
| @@ -57,10 +57,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, | |||
| 57 | set_current_state(TASK_INTERRUPTIBLE); | 57 | set_current_state(TASK_INTERRUPTIBLE); |
| 58 | 58 | ||
| 59 | while (list->head == list->tail) { | 59 | while (list->head == list->tail) { |
| 60 | if (file->f_flags & O_NONBLOCK) { | ||
| 61 | ret = -EAGAIN; | ||
| 62 | break; | ||
| 63 | } | ||
| 64 | if (signal_pending(current)) { | 60 | if (signal_pending(current)) { |
| 65 | ret = -ERESTARTSYS; | 61 | ret = -ERESTARTSYS; |
| 66 | break; | 62 | break; |
| @@ -69,6 +65,10 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, | |||
| 69 | ret = -EIO; | 65 | ret = -EIO; |
| 70 | break; | 66 | break; |
| 71 | } | 67 | } |
| 68 | if (file->f_flags & O_NONBLOCK) { | ||
| 69 | ret = -EAGAIN; | ||
| 70 | break; | ||
| 71 | } | ||
| 72 | 72 | ||
| 73 | /* allow O_NONBLOCK to work well from other threads */ | 73 | /* allow O_NONBLOCK to work well from other threads */ |
| 74 | mutex_unlock(&list->read_mutex); | 74 | mutex_unlock(&list->read_mutex); |
| @@ -295,6 +295,13 @@ out: | |||
| 295 | 295 | ||
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | static int hidraw_fasync(int fd, struct file *file, int on) | ||
| 299 | { | ||
| 300 | struct hidraw_list *list = file->private_data; | ||
| 301 | |||
| 302 | return fasync_helper(fd, file, on, &list->fasync); | ||
| 303 | } | ||
| 304 | |||
| 298 | static int hidraw_release(struct inode * inode, struct file * file) | 305 | static int hidraw_release(struct inode * inode, struct file * file) |
| 299 | { | 306 | { |
| 300 | unsigned int minor = iminor(inode); | 307 | unsigned int minor = iminor(inode); |
| @@ -438,6 +445,7 @@ static const struct file_operations hidraw_ops = { | |||
| 438 | .open = hidraw_open, | 445 | .open = hidraw_open, |
| 439 | .release = hidraw_release, | 446 | .release = hidraw_release, |
| 440 | .unlocked_ioctl = hidraw_ioctl, | 447 | .unlocked_ioctl = hidraw_ioctl, |
| 448 | .fasync = hidraw_fasync, | ||
| 441 | #ifdef CONFIG_COMPAT | 449 | #ifdef CONFIG_COMPAT |
| 442 | .compat_ioctl = hidraw_ioctl, | 450 | .compat_ioctl = hidraw_ioctl, |
| 443 | #endif | 451 | #endif |
diff --git a/drivers/hid/i2c-hid/Kconfig b/drivers/hid/i2c-hid/Kconfig new file mode 100644 index 000000000000..b66617a020bd --- /dev/null +++ b/drivers/hid/i2c-hid/Kconfig | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | menu "I2C HID support" | ||
| 2 | depends on I2C | ||
| 3 | |||
| 4 | config I2C_HID | ||
| 5 | tristate "HID over I2C transport layer" | ||
| 6 | default n | ||
| 7 | depends on I2C && INPUT | ||
| 8 | select HID | ||
| 9 | ---help--- | ||
| 10 | Say Y here if you use a keyboard, a touchpad, a touchscreen, or any | ||
| 11 | other HID based devices which is connected to your computer via I2C. | ||
| 12 | |||
| 13 | If unsure, say N. | ||
| 14 | |||
| 15 | This support is also available as a module. If so, the module | ||
| 16 | will be called i2c-hid. | ||
| 17 | |||
| 18 | endmenu | ||
diff --git a/drivers/hid/i2c-hid/Makefile b/drivers/hid/i2c-hid/Makefile new file mode 100644 index 000000000000..832d8f9aaba2 --- /dev/null +++ b/drivers/hid/i2c-hid/Makefile | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the I2C input drivers | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_I2C_HID) += i2c-hid.o | ||
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c new file mode 100644 index 000000000000..9ef222442ca0 --- /dev/null +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
| @@ -0,0 +1,979 @@ | |||
| 1 | /* | ||
| 2 | * HID over I2C protocol implementation | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> | ||
| 5 | * Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France | ||
| 6 | * Copyright (c) 2012 Red Hat, Inc | ||
| 7 | * | ||
| 8 | * This code is partly based on "USB HID support for Linux": | ||
| 9 | * | ||
| 10 | * Copyright (c) 1999 Andreas Gal | ||
| 11 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | ||
| 12 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | ||
| 13 | * Copyright (c) 2007-2008 Oliver Neukum | ||
| 14 | * Copyright (c) 2006-2010 Jiri Kosina | ||
| 15 | * | ||
| 16 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 17 | * License. See the file COPYING in the main directory of this archive for | ||
| 18 | * more details. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/i2c.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <linux/input.h> | ||
| 25 | #include <linux/delay.h> | ||
| 26 | #include <linux/slab.h> | ||
| 27 | #include <linux/pm.h> | ||
| 28 | #include <linux/device.h> | ||
| 29 | #include <linux/wait.h> | ||
| 30 | #include <linux/err.h> | ||
| 31 | #include <linux/string.h> | ||
| 32 | #include <linux/list.h> | ||
| 33 | #include <linux/jiffies.h> | ||
| 34 | #include <linux/kernel.h> | ||
| 35 | #include <linux/hid.h> | ||
| 36 | #include <linux/mutex.h> | ||
| 37 | |||
| 38 | #include <linux/i2c/i2c-hid.h> | ||
| 39 | |||
| 40 | /* flags */ | ||
| 41 | #define I2C_HID_STARTED (1 << 0) | ||
| 42 | #define I2C_HID_RESET_PENDING (1 << 1) | ||
| 43 | #define I2C_HID_READ_PENDING (1 << 2) | ||
| 44 | |||
| 45 | #define I2C_HID_PWR_ON 0x00 | ||
| 46 | #define I2C_HID_PWR_SLEEP 0x01 | ||
| 47 | |||
| 48 | /* debug option */ | ||
| 49 | static bool debug; | ||
| 50 | module_param(debug, bool, 0444); | ||
| 51 | MODULE_PARM_DESC(debug, "print a lot of debug information"); | ||
| 52 | |||
| 53 | #define i2c_hid_dbg(ihid, fmt, arg...) \ | ||
| 54 | do { \ | ||
| 55 | if (debug) \ | ||
| 56 | dev_printk(KERN_DEBUG, &(ihid)->client->dev, fmt, ##arg); \ | ||
| 57 | } while (0) | ||
| 58 | |||
| 59 | struct i2c_hid_desc { | ||
| 60 | __le16 wHIDDescLength; | ||
| 61 | __le16 bcdVersion; | ||
| 62 | __le16 wReportDescLength; | ||
| 63 | __le16 wReportDescRegister; | ||
| 64 | __le16 wInputRegister; | ||
| 65 | __le16 wMaxInputLength; | ||
| 66 | __le16 wOutputRegister; | ||
| 67 | __le16 wMaxOutputLength; | ||
| 68 | __le16 wCommandRegister; | ||
| 69 | __le16 wDataRegister; | ||
| 70 | __le16 wVendorID; | ||
| 71 | __le16 wProductID; | ||
| 72 | __le16 wVersionID; | ||
| 73 | __le32 reserved; | ||
| 74 | } __packed; | ||
| 75 | |||
| 76 | struct i2c_hid_cmd { | ||
| 77 | unsigned int registerIndex; | ||
| 78 | __u8 opcode; | ||
| 79 | unsigned int length; | ||
| 80 | bool wait; | ||
| 81 | }; | ||
| 82 | |||
| 83 | union command { | ||
| 84 | u8 data[0]; | ||
| 85 | struct cmd { | ||
| 86 | __le16 reg; | ||
| 87 | __u8 reportTypeID; | ||
| 88 | __u8 opcode; | ||
| 89 | } __packed c; | ||
| 90 | }; | ||
| 91 | |||
| 92 | #define I2C_HID_CMD(opcode_) \ | ||
| 93 | .opcode = opcode_, .length = 4, \ | ||
| 94 | .registerIndex = offsetof(struct i2c_hid_desc, wCommandRegister) | ||
| 95 | |||
| 96 | /* fetch HID descriptor */ | ||
| 97 | static const struct i2c_hid_cmd hid_descr_cmd = { .length = 2 }; | ||
| 98 | /* fetch report descriptors */ | ||
| 99 | static const struct i2c_hid_cmd hid_report_descr_cmd = { | ||
| 100 | .registerIndex = offsetof(struct i2c_hid_desc, | ||
| 101 | wReportDescRegister), | ||
| 102 | .opcode = 0x00, | ||
| 103 | .length = 2 }; | ||
| 104 | /* commands */ | ||
| 105 | static const struct i2c_hid_cmd hid_reset_cmd = { I2C_HID_CMD(0x01), | ||
| 106 | .wait = true }; | ||
| 107 | static const struct i2c_hid_cmd hid_get_report_cmd = { I2C_HID_CMD(0x02) }; | ||
| 108 | static const struct i2c_hid_cmd hid_set_report_cmd = { I2C_HID_CMD(0x03) }; | ||
| 109 | static const struct i2c_hid_cmd hid_set_power_cmd = { I2C_HID_CMD(0x08) }; | ||
| 110 | |||
| 111 | /* | ||
| 112 | * These definitions are not used here, but are defined by the spec. | ||
| 113 | * Keeping them here for documentation purposes. | ||
| 114 | * | ||
| 115 | * static const struct i2c_hid_cmd hid_get_idle_cmd = { I2C_HID_CMD(0x04) }; | ||
| 116 | * static const struct i2c_hid_cmd hid_set_idle_cmd = { I2C_HID_CMD(0x05) }; | ||
| 117 | * static const struct i2c_hid_cmd hid_get_protocol_cmd = { I2C_HID_CMD(0x06) }; | ||
| 118 | * static const struct i2c_hid_cmd hid_set_protocol_cmd = { I2C_HID_CMD(0x07) }; | ||
| 119 | */ | ||
| 120 | |||
| 121 | static DEFINE_MUTEX(i2c_hid_open_mut); | ||
| 122 | |||
| 123 | /* The main device structure */ | ||
| 124 | struct i2c_hid { | ||
| 125 | struct i2c_client *client; /* i2c client */ | ||
| 126 | struct hid_device *hid; /* pointer to corresponding HID dev */ | ||
| 127 | union { | ||
| 128 | __u8 hdesc_buffer[sizeof(struct i2c_hid_desc)]; | ||
| 129 | struct i2c_hid_desc hdesc; /* the HID Descriptor */ | ||
| 130 | }; | ||
| 131 | __le16 wHIDDescRegister; /* location of the i2c | ||
| 132 | * register of the HID | ||
| 133 | * descriptor. */ | ||
| 134 | unsigned int bufsize; /* i2c buffer size */ | ||
| 135 | char *inbuf; /* Input buffer */ | ||
| 136 | char *cmdbuf; /* Command buffer */ | ||
| 137 | char *argsbuf; /* Command arguments buffer */ | ||
| 138 | |||
| 139 | unsigned long flags; /* device flags */ | ||
| 140 | |||
| 141 | wait_queue_head_t wait; /* For waiting the interrupt */ | ||
| 142 | }; | ||
| 143 | |||
| 144 | static int __i2c_hid_command(struct i2c_client *client, | ||
| 145 | const struct i2c_hid_cmd *command, u8 reportID, | ||
| 146 | u8 reportType, u8 *args, int args_len, | ||
| 147 | unsigned char *buf_recv, int data_len) | ||
| 148 | { | ||
| 149 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 150 | union command *cmd = (union command *)ihid->cmdbuf; | ||
| 151 | int ret; | ||
| 152 | struct i2c_msg msg[2]; | ||
| 153 | int msg_num = 1; | ||
| 154 | |||
| 155 | int length = command->length; | ||
| 156 | bool wait = command->wait; | ||
| 157 | unsigned int registerIndex = command->registerIndex; | ||
| 158 | |||
| 159 | /* special case for hid_descr_cmd */ | ||
| 160 | if (command == &hid_descr_cmd) { | ||
| 161 | cmd->c.reg = ihid->wHIDDescRegister; | ||
| 162 | } else { | ||
| 163 | cmd->data[0] = ihid->hdesc_buffer[registerIndex]; | ||
| 164 | cmd->data[1] = ihid->hdesc_buffer[registerIndex + 1]; | ||
| 165 | } | ||
| 166 | |||
| 167 | if (length > 2) { | ||
| 168 | cmd->c.opcode = command->opcode; | ||
| 169 | cmd->c.reportTypeID = reportID | reportType << 4; | ||
| 170 | } | ||
| 171 | |||
| 172 | memcpy(cmd->data + length, args, args_len); | ||
| 173 | length += args_len; | ||
| 174 | |||
| 175 | i2c_hid_dbg(ihid, "%s: cmd=%*ph\n", __func__, length, cmd->data); | ||
| 176 | |||
| 177 | msg[0].addr = client->addr; | ||
| 178 | msg[0].flags = client->flags & I2C_M_TEN; | ||
| 179 | msg[0].len = length; | ||
| 180 | msg[0].buf = cmd->data; | ||
| 181 | if (data_len > 0) { | ||
| 182 | msg[1].addr = client->addr; | ||
| 183 | msg[1].flags = client->flags & I2C_M_TEN; | ||
| 184 | msg[1].flags |= I2C_M_RD; | ||
| 185 | msg[1].len = data_len; | ||
| 186 | msg[1].buf = buf_recv; | ||
| 187 | msg_num = 2; | ||
| 188 | set_bit(I2C_HID_READ_PENDING, &ihid->flags); | ||
| 189 | } | ||
| 190 | |||
| 191 | if (wait) | ||
| 192 | set_bit(I2C_HID_RESET_PENDING, &ihid->flags); | ||
| 193 | |||
| 194 | ret = i2c_transfer(client->adapter, msg, msg_num); | ||
| 195 | |||
| 196 | if (data_len > 0) | ||
| 197 | clear_bit(I2C_HID_READ_PENDING, &ihid->flags); | ||
| 198 | |||
| 199 | if (ret != msg_num) | ||
| 200 | return ret < 0 ? ret : -EIO; | ||
| 201 | |||
| 202 | ret = 0; | ||
| 203 | |||
| 204 | if (wait) { | ||
| 205 | i2c_hid_dbg(ihid, "%s: waiting...\n", __func__); | ||
| 206 | if (!wait_event_timeout(ihid->wait, | ||
| 207 | !test_bit(I2C_HID_RESET_PENDING, &ihid->flags), | ||
| 208 | msecs_to_jiffies(5000))) | ||
| 209 | ret = -ENODATA; | ||
| 210 | i2c_hid_dbg(ihid, "%s: finished.\n", __func__); | ||
| 211 | } | ||
| 212 | |||
| 213 | return ret; | ||
| 214 | } | ||
| 215 | |||
| 216 | static int i2c_hid_command(struct i2c_client *client, | ||
| 217 | const struct i2c_hid_cmd *command, | ||
| 218 | unsigned char *buf_recv, int data_len) | ||
| 219 | { | ||
| 220 | return __i2c_hid_command(client, command, 0, 0, NULL, 0, | ||
| 221 | buf_recv, data_len); | ||
| 222 | } | ||
| 223 | |||
| 224 | static int i2c_hid_get_report(struct i2c_client *client, u8 reportType, | ||
| 225 | u8 reportID, unsigned char *buf_recv, int data_len) | ||
| 226 | { | ||
| 227 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 228 | u8 args[3]; | ||
| 229 | int ret; | ||
| 230 | int args_len = 0; | ||
| 231 | u16 readRegister = le16_to_cpu(ihid->hdesc.wDataRegister); | ||
| 232 | |||
| 233 | i2c_hid_dbg(ihid, "%s\n", __func__); | ||
| 234 | |||
| 235 | if (reportID >= 0x0F) { | ||
| 236 | args[args_len++] = reportID; | ||
| 237 | reportID = 0x0F; | ||
| 238 | } | ||
| 239 | |||
| 240 | args[args_len++] = readRegister & 0xFF; | ||
| 241 | args[args_len++] = readRegister >> 8; | ||
| 242 | |||
| 243 | ret = __i2c_hid_command(client, &hid_get_report_cmd, reportID, | ||
| 244 | reportType, args, args_len, buf_recv, data_len); | ||
| 245 | if (ret) { | ||
| 246 | dev_err(&client->dev, | ||
| 247 | "failed to retrieve report from device.\n"); | ||
| 248 | return ret; | ||
| 249 | } | ||
| 250 | |||
| 251 | return 0; | ||
| 252 | } | ||
| 253 | |||
| 254 | static int i2c_hid_set_report(struct i2c_client *client, u8 reportType, | ||
| 255 | u8 reportID, unsigned char *buf, size_t data_len) | ||
| 256 | { | ||
| 257 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 258 | u8 *args = ihid->argsbuf; | ||
| 259 | int ret; | ||
| 260 | u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister); | ||
| 261 | |||
| 262 | /* hidraw already checked that data_len < HID_MAX_BUFFER_SIZE */ | ||
| 263 | u16 size = 2 /* size */ + | ||
| 264 | (reportID ? 1 : 0) /* reportID */ + | ||
| 265 | data_len /* buf */; | ||
| 266 | int args_len = (reportID >= 0x0F ? 1 : 0) /* optional third byte */ + | ||
| 267 | 2 /* dataRegister */ + | ||
| 268 | size /* args */; | ||
| 269 | int index = 0; | ||
| 270 | |||
| 271 | i2c_hid_dbg(ihid, "%s\n", __func__); | ||
| 272 | |||
| 273 | if (reportID >= 0x0F) { | ||
| 274 | args[index++] = reportID; | ||
| 275 | reportID = 0x0F; | ||
| 276 | } | ||
| 277 | |||
| 278 | args[index++] = dataRegister & 0xFF; | ||
| 279 | args[index++] = dataRegister >> 8; | ||
| 280 | |||
| 281 | args[index++] = size & 0xFF; | ||
| 282 | args[index++] = size >> 8; | ||
| 283 | |||
| 284 | if (reportID) | ||
| 285 | args[index++] = reportID; | ||
| 286 | |||
| 287 | memcpy(&args[index], buf, data_len); | ||
| 288 | |||
| 289 | ret = __i2c_hid_command(client, &hid_set_report_cmd, reportID, | ||
| 290 | reportType, args, args_len, NULL, 0); | ||
| 291 | if (ret) { | ||
| 292 | dev_err(&client->dev, "failed to set a report to device.\n"); | ||
| 293 | return ret; | ||
| 294 | } | ||
| 295 | |||
| 296 | return data_len; | ||
| 297 | } | ||
| 298 | |||
| 299 | static int i2c_hid_set_power(struct i2c_client *client, int power_state) | ||
| 300 | { | ||
| 301 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 302 | int ret; | ||
| 303 | |||
| 304 | i2c_hid_dbg(ihid, "%s\n", __func__); | ||
| 305 | |||
| 306 | ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, | ||
| 307 | 0, NULL, 0, NULL, 0); | ||
| 308 | if (ret) | ||
| 309 | dev_err(&client->dev, "failed to change power setting.\n"); | ||
| 310 | |||
| 311 | return ret; | ||
| 312 | } | ||
| 313 | |||
| 314 | static int i2c_hid_hwreset(struct i2c_client *client) | ||
| 315 | { | ||
| 316 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 317 | int ret; | ||
| 318 | |||
| 319 | i2c_hid_dbg(ihid, "%s\n", __func__); | ||
| 320 | |||
| 321 | ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); | ||
| 322 | if (ret) | ||
| 323 | return ret; | ||
| 324 | |||
| 325 | i2c_hid_dbg(ihid, "resetting...\n"); | ||
| 326 | |||
| 327 | ret = i2c_hid_command(client, &hid_reset_cmd, NULL, 0); | ||
| 328 | if (ret) { | ||
| 329 | dev_err(&client->dev, "failed to reset device.\n"); | ||
| 330 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); | ||
| 331 | return ret; | ||
| 332 | } | ||
| 333 | |||
| 334 | return 0; | ||
| 335 | } | ||
| 336 | |||
| 337 | static void i2c_hid_get_input(struct i2c_hid *ihid) | ||
| 338 | { | ||
| 339 | int ret, ret_size; | ||
| 340 | int size = le16_to_cpu(ihid->hdesc.wMaxInputLength); | ||
| 341 | |||
| 342 | ret = i2c_master_recv(ihid->client, ihid->inbuf, size); | ||
| 343 | if (ret != size) { | ||
| 344 | if (ret < 0) | ||
| 345 | return; | ||
| 346 | |||
| 347 | dev_err(&ihid->client->dev, "%s: got %d data instead of %d\n", | ||
| 348 | __func__, ret, size); | ||
| 349 | return; | ||
| 350 | } | ||
| 351 | |||
| 352 | ret_size = ihid->inbuf[0] | ihid->inbuf[1] << 8; | ||
| 353 | |||
| 354 | if (!ret_size) { | ||
| 355 | /* host or device initiated RESET completed */ | ||
| 356 | if (test_and_clear_bit(I2C_HID_RESET_PENDING, &ihid->flags)) | ||
| 357 | wake_up(&ihid->wait); | ||
| 358 | return; | ||
| 359 | } | ||
| 360 | |||
| 361 | if (ret_size > size) { | ||
| 362 | dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", | ||
| 363 | __func__, size, ret_size); | ||
| 364 | return; | ||
| 365 | } | ||
| 366 | |||
| 367 | i2c_hid_dbg(ihid, "input: %*ph\n", ret_size, ihid->inbuf); | ||
| 368 | |||
| 369 | if (test_bit(I2C_HID_STARTED, &ihid->flags)) | ||
| 370 | hid_input_report(ihid->hid, HID_INPUT_REPORT, ihid->inbuf + 2, | ||
| 371 | ret_size - 2, 1); | ||
| 372 | |||
| 373 | return; | ||
| 374 | } | ||
| 375 | |||
| 376 | static irqreturn_t i2c_hid_irq(int irq, void *dev_id) | ||
| 377 | { | ||
| 378 | struct i2c_hid *ihid = dev_id; | ||
| 379 | |||
| 380 | if (test_bit(I2C_HID_READ_PENDING, &ihid->flags)) | ||
| 381 | return IRQ_HANDLED; | ||
| 382 | |||
| 383 | i2c_hid_get_input(ihid); | ||
| 384 | |||
| 385 | return IRQ_HANDLED; | ||
| 386 | } | ||
| 387 | |||
| 388 | static int i2c_hid_get_report_length(struct hid_report *report) | ||
| 389 | { | ||
| 390 | return ((report->size - 1) >> 3) + 1 + | ||
| 391 | report->device->report_enum[report->type].numbered + 2; | ||
| 392 | } | ||
| 393 | |||
| 394 | static void i2c_hid_init_report(struct hid_report *report, u8 *buffer, | ||
| 395 | size_t bufsize) | ||
| 396 | { | ||
| 397 | struct hid_device *hid = report->device; | ||
| 398 | struct i2c_client *client = hid->driver_data; | ||
| 399 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 400 | unsigned int size, ret_size; | ||
| 401 | |||
| 402 | size = i2c_hid_get_report_length(report); | ||
| 403 | if (i2c_hid_get_report(client, | ||
| 404 | report->type == HID_FEATURE_REPORT ? 0x03 : 0x01, | ||
| 405 | report->id, buffer, size)) | ||
| 406 | return; | ||
| 407 | |||
| 408 | i2c_hid_dbg(ihid, "report (len=%d): %*ph\n", size, size, ihid->inbuf); | ||
| 409 | |||
| 410 | ret_size = buffer[0] | (buffer[1] << 8); | ||
| 411 | |||
| 412 | if (ret_size != size) { | ||
| 413 | dev_err(&client->dev, "error in %s size:%d / ret_size:%d\n", | ||
| 414 | __func__, size, ret_size); | ||
| 415 | return; | ||
| 416 | } | ||
| 417 | |||
| 418 | /* hid->driver_lock is held as we are in probe function, | ||
| 419 | * we just need to setup the input fields, so using | ||
| 420 | * hid_report_raw_event is safe. */ | ||
| 421 | hid_report_raw_event(hid, report->type, buffer + 2, size - 2, 1); | ||
| 422 | } | ||
| 423 | |||
| 424 | /* | ||
| 425 | * Initialize all reports | ||
| 426 | */ | ||
| 427 | static void i2c_hid_init_reports(struct hid_device *hid) | ||
| 428 | { | ||
| 429 | struct hid_report *report; | ||
| 430 | struct i2c_client *client = hid->driver_data; | ||
| 431 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 432 | u8 *inbuf = kzalloc(ihid->bufsize, GFP_KERNEL); | ||
| 433 | |||
| 434 | if (!inbuf) { | ||
| 435 | dev_err(&client->dev, "can not retrieve initial reports\n"); | ||
| 436 | return; | ||
| 437 | } | ||
| 438 | |||
| 439 | list_for_each_entry(report, | ||
| 440 | &hid->report_enum[HID_INPUT_REPORT].report_list, list) | ||
| 441 | i2c_hid_init_report(report, inbuf, ihid->bufsize); | ||
| 442 | |||
| 443 | list_for_each_entry(report, | ||
| 444 | &hid->report_enum[HID_FEATURE_REPORT].report_list, list) | ||
| 445 | i2c_hid_init_report(report, inbuf, ihid->bufsize); | ||
| 446 | |||
| 447 | kfree(inbuf); | ||
| 448 | } | ||
| 449 | |||
| 450 | /* | ||
| 451 | * Traverse the supplied list of reports and find the longest | ||
| 452 | */ | ||
| 453 | static void i2c_hid_find_max_report(struct hid_device *hid, unsigned int type, | ||
| 454 | unsigned int *max) | ||
| 455 | { | ||
| 456 | struct hid_report *report; | ||
| 457 | unsigned int size; | ||
| 458 | |||
| 459 | /* We should not rely on wMaxInputLength, as some devices may set it to | ||
| 460 | * a wrong length. */ | ||
| 461 | list_for_each_entry(report, &hid->report_enum[type].report_list, list) { | ||
| 462 | size = i2c_hid_get_report_length(report); | ||
| 463 | if (*max < size) | ||
| 464 | *max = size; | ||
| 465 | } | ||
| 466 | } | ||
| 467 | |||
| 468 | static void i2c_hid_free_buffers(struct i2c_hid *ihid) | ||
| 469 | { | ||
| 470 | kfree(ihid->inbuf); | ||
| 471 | kfree(ihid->argsbuf); | ||
| 472 | kfree(ihid->cmdbuf); | ||
| 473 | ihid->inbuf = NULL; | ||
| 474 | ihid->cmdbuf = NULL; | ||
| 475 | ihid->argsbuf = NULL; | ||
| 476 | ihid->bufsize = 0; | ||
| 477 | } | ||
| 478 | |||
| 479 | static int i2c_hid_alloc_buffers(struct i2c_hid *ihid, size_t report_size) | ||
| 480 | { | ||
| 481 | /* the worst case is computed from the set_report command with a | ||
| 482 | * reportID > 15 and the maximum report length */ | ||
| 483 | int args_len = sizeof(__u8) + /* optional ReportID byte */ | ||
| 484 | sizeof(__u16) + /* data register */ | ||
| 485 | sizeof(__u16) + /* size of the report */ | ||
| 486 | report_size; /* report */ | ||
| 487 | |||
| 488 | ihid->inbuf = kzalloc(report_size, GFP_KERNEL); | ||
| 489 | ihid->argsbuf = kzalloc(args_len, GFP_KERNEL); | ||
| 490 | ihid->cmdbuf = kzalloc(sizeof(union command) + args_len, GFP_KERNEL); | ||
| 491 | |||
| 492 | if (!ihid->inbuf || !ihid->argsbuf || !ihid->cmdbuf) { | ||
| 493 | i2c_hid_free_buffers(ihid); | ||
| 494 | return -ENOMEM; | ||
| 495 | } | ||
| 496 | |||
| 497 | ihid->bufsize = report_size; | ||
| 498 | |||
| 499 | return 0; | ||
| 500 | } | ||
| 501 | |||
| 502 | static int i2c_hid_get_raw_report(struct hid_device *hid, | ||
| 503 | unsigned char report_number, __u8 *buf, size_t count, | ||
| 504 | unsigned char report_type) | ||
| 505 | { | ||
| 506 | struct i2c_client *client = hid->driver_data; | ||
| 507 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 508 | size_t ret_count, ask_count; | ||
| 509 | int ret; | ||
| 510 | |||
| 511 | if (report_type == HID_OUTPUT_REPORT) | ||
| 512 | return -EINVAL; | ||
| 513 | |||
| 514 | /* +2 bytes to include the size of the reply in the query buffer */ | ||
| 515 | ask_count = min(count + 2, (size_t)ihid->bufsize); | ||
| 516 | |||
| 517 | ret = i2c_hid_get_report(client, | ||
| 518 | report_type == HID_FEATURE_REPORT ? 0x03 : 0x01, | ||
| 519 | report_number, ihid->inbuf, ask_count); | ||
| 520 | |||
| 521 | if (ret < 0) | ||
| 522 | return ret; | ||
| 523 | |||
| 524 | ret_count = ihid->inbuf[0] | (ihid->inbuf[1] << 8); | ||
| 525 | |||
| 526 | if (ret_count <= 2) | ||
| 527 | return 0; | ||
| 528 | |||
| 529 | ret_count = min(ret_count, ask_count); | ||
| 530 | |||
| 531 | /* The query buffer contains the size, dropping it in the reply */ | ||
| 532 | count = min(count, ret_count - 2); | ||
| 533 | memcpy(buf, ihid->inbuf + 2, count); | ||
| 534 | |||
| 535 | return count; | ||
| 536 | } | ||
| 537 | |||
| 538 | static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, | ||
| 539 | size_t count, unsigned char report_type) | ||
| 540 | { | ||
| 541 | struct i2c_client *client = hid->driver_data; | ||
| 542 | int report_id = buf[0]; | ||
| 543 | |||
| 544 | if (report_type == HID_INPUT_REPORT) | ||
| 545 | return -EINVAL; | ||
| 546 | |||
| 547 | return i2c_hid_set_report(client, | ||
| 548 | report_type == HID_FEATURE_REPORT ? 0x03 : 0x02, | ||
| 549 | report_id, buf, count); | ||
| 550 | } | ||
| 551 | |||
| 552 | static int i2c_hid_parse(struct hid_device *hid) | ||
| 553 | { | ||
| 554 | struct i2c_client *client = hid->driver_data; | ||
| 555 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 556 | struct i2c_hid_desc *hdesc = &ihid->hdesc; | ||
| 557 | unsigned int rsize; | ||
| 558 | char *rdesc; | ||
| 559 | int ret; | ||
| 560 | int tries = 3; | ||
| 561 | |||
| 562 | i2c_hid_dbg(ihid, "entering %s\n", __func__); | ||
| 563 | |||
| 564 | rsize = le16_to_cpu(hdesc->wReportDescLength); | ||
| 565 | if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { | ||
| 566 | dbg_hid("weird size of report descriptor (%u)\n", rsize); | ||
| 567 | return -EINVAL; | ||
| 568 | } | ||
| 569 | |||
| 570 | do { | ||
| 571 | ret = i2c_hid_hwreset(client); | ||
| 572 | if (ret) | ||
| 573 | msleep(1000); | ||
| 574 | } while (tries-- > 0 && ret); | ||
| 575 | |||
| 576 | if (ret) | ||
| 577 | return ret; | ||
| 578 | |||
| 579 | rdesc = kzalloc(rsize, GFP_KERNEL); | ||
| 580 | |||
| 581 | if (!rdesc) { | ||
| 582 | dbg_hid("couldn't allocate rdesc memory\n"); | ||
| 583 | return -ENOMEM; | ||
| 584 | } | ||
| 585 | |||
| 586 | i2c_hid_dbg(ihid, "asking HID report descriptor\n"); | ||
| 587 | |||
| 588 | ret = i2c_hid_command(client, &hid_report_descr_cmd, rdesc, rsize); | ||
| 589 | if (ret) { | ||
| 590 | hid_err(hid, "reading report descriptor failed\n"); | ||
| 591 | kfree(rdesc); | ||
| 592 | return -EIO; | ||
| 593 | } | ||
| 594 | |||
| 595 | i2c_hid_dbg(ihid, "Report Descriptor: %*ph\n", rsize, rdesc); | ||
| 596 | |||
| 597 | ret = hid_parse_report(hid, rdesc, rsize); | ||
| 598 | kfree(rdesc); | ||
| 599 | if (ret) { | ||
| 600 | dbg_hid("parsing report descriptor failed\n"); | ||
| 601 | return ret; | ||
| 602 | } | ||
| 603 | |||
| 604 | return 0; | ||
| 605 | } | ||
| 606 | |||
| 607 | static int i2c_hid_start(struct hid_device *hid) | ||
| 608 | { | ||
| 609 | struct i2c_client *client = hid->driver_data; | ||
| 610 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 611 | int ret; | ||
| 612 | unsigned int bufsize = HID_MIN_BUFFER_SIZE; | ||
| 613 | |||
| 614 | i2c_hid_find_max_report(hid, HID_INPUT_REPORT, &bufsize); | ||
| 615 | i2c_hid_find_max_report(hid, HID_OUTPUT_REPORT, &bufsize); | ||
| 616 | i2c_hid_find_max_report(hid, HID_FEATURE_REPORT, &bufsize); | ||
| 617 | |||
| 618 | if (bufsize > ihid->bufsize) { | ||
| 619 | i2c_hid_free_buffers(ihid); | ||
| 620 | |||
| 621 | ret = i2c_hid_alloc_buffers(ihid, bufsize); | ||
| 622 | |||
| 623 | if (ret) | ||
| 624 | return ret; | ||
| 625 | } | ||
| 626 | |||
| 627 | if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS)) | ||
| 628 | i2c_hid_init_reports(hid); | ||
| 629 | |||
| 630 | return 0; | ||
| 631 | } | ||
| 632 | |||
| 633 | static void i2c_hid_stop(struct hid_device *hid) | ||
| 634 | { | ||
| 635 | struct i2c_client *client = hid->driver_data; | ||
| 636 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 637 | |||
| 638 | hid->claimed = 0; | ||
| 639 | |||
| 640 | i2c_hid_free_buffers(ihid); | ||
| 641 | } | ||
| 642 | |||
| 643 | static int i2c_hid_open(struct hid_device *hid) | ||
| 644 | { | ||
| 645 | struct i2c_client *client = hid->driver_data; | ||
| 646 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 647 | int ret = 0; | ||
| 648 | |||
| 649 | mutex_lock(&i2c_hid_open_mut); | ||
| 650 | if (!hid->open++) { | ||
| 651 | ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); | ||
| 652 | if (ret) { | ||
| 653 | hid->open--; | ||
| 654 | goto done; | ||
| 655 | } | ||
| 656 | set_bit(I2C_HID_STARTED, &ihid->flags); | ||
| 657 | } | ||
| 658 | done: | ||
| 659 | mutex_unlock(&i2c_hid_open_mut); | ||
| 660 | return ret; | ||
| 661 | } | ||
| 662 | |||
| 663 | static void i2c_hid_close(struct hid_device *hid) | ||
| 664 | { | ||
| 665 | struct i2c_client *client = hid->driver_data; | ||
| 666 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 667 | |||
| 668 | /* protecting hid->open to make sure we don't restart | ||
| 669 | * data acquistion due to a resumption we no longer | ||
| 670 | * care about | ||
| 671 | */ | ||
| 672 | mutex_lock(&i2c_hid_open_mut); | ||
| 673 | if (!--hid->open) { | ||
| 674 | clear_bit(I2C_HID_STARTED, &ihid->flags); | ||
| 675 | |||
| 676 | /* Save some power */ | ||
| 677 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); | ||
| 678 | } | ||
| 679 | mutex_unlock(&i2c_hid_open_mut); | ||
| 680 | } | ||
| 681 | |||
| 682 | static int i2c_hid_power(struct hid_device *hid, int lvl) | ||
| 683 | { | ||
| 684 | struct i2c_client *client = hid->driver_data; | ||
| 685 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 686 | int ret = 0; | ||
| 687 | |||
| 688 | i2c_hid_dbg(ihid, "%s lvl:%d\n", __func__, lvl); | ||
| 689 | |||
| 690 | switch (lvl) { | ||
| 691 | case PM_HINT_FULLON: | ||
| 692 | ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); | ||
| 693 | break; | ||
| 694 | case PM_HINT_NORMAL: | ||
| 695 | ret = i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); | ||
| 696 | break; | ||
| 697 | } | ||
| 698 | return ret; | ||
| 699 | } | ||
| 700 | |||
| 701 | static int i2c_hid_hidinput_input_event(struct input_dev *dev, | ||
| 702 | unsigned int type, unsigned int code, int value) | ||
| 703 | { | ||
| 704 | struct hid_device *hid = input_get_drvdata(dev); | ||
| 705 | struct hid_field *field; | ||
| 706 | int offset; | ||
| 707 | |||
| 708 | if (type == EV_FF) | ||
| 709 | return input_ff_event(dev, type, code, value); | ||
| 710 | |||
| 711 | if (type != EV_LED) | ||
| 712 | return -1; | ||
| 713 | |||
| 714 | offset = hidinput_find_field(hid, type, code, &field); | ||
| 715 | |||
| 716 | if (offset == -1) { | ||
| 717 | hid_warn(dev, "event field not found\n"); | ||
| 718 | return -1; | ||
| 719 | } | ||
| 720 | |||
| 721 | return hid_set_field(field, offset, value); | ||
| 722 | } | ||
| 723 | |||
| 724 | static struct hid_ll_driver i2c_hid_ll_driver = { | ||
| 725 | .parse = i2c_hid_parse, | ||
| 726 | .start = i2c_hid_start, | ||
| 727 | .stop = i2c_hid_stop, | ||
| 728 | .open = i2c_hid_open, | ||
| 729 | .close = i2c_hid_close, | ||
| 730 | .power = i2c_hid_power, | ||
| 731 | .hidinput_input_event = i2c_hid_hidinput_input_event, | ||
| 732 | }; | ||
| 733 | |||
| 734 | static int __devinit i2c_hid_init_irq(struct i2c_client *client) | ||
| 735 | { | ||
| 736 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 737 | int ret; | ||
| 738 | |||
| 739 | dev_dbg(&client->dev, "Requesting IRQ: %d\n", client->irq); | ||
| 740 | |||
| 741 | ret = request_threaded_irq(client->irq, NULL, i2c_hid_irq, | ||
| 742 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
| 743 | client->name, ihid); | ||
| 744 | if (ret < 0) { | ||
| 745 | dev_warn(&client->dev, | ||
| 746 | "Could not register for %s interrupt, irq = %d," | ||
| 747 | " ret = %d\n", | ||
| 748 | client->name, client->irq, ret); | ||
| 749 | |||
| 750 | return ret; | ||
| 751 | } | ||
| 752 | |||
| 753 | return 0; | ||
| 754 | } | ||
| 755 | |||
| 756 | static int __devinit i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid) | ||
| 757 | { | ||
| 758 | struct i2c_client *client = ihid->client; | ||
| 759 | struct i2c_hid_desc *hdesc = &ihid->hdesc; | ||
| 760 | unsigned int dsize; | ||
| 761 | int ret; | ||
| 762 | |||
| 763 | /* Fetch the length of HID description, retrieve the 4 first bytes: | ||
| 764 | * bytes 0-1 -> length | ||
| 765 | * bytes 2-3 -> bcdVersion (has to be 1.00) */ | ||
| 766 | ret = i2c_hid_command(client, &hid_descr_cmd, ihid->hdesc_buffer, 4); | ||
| 767 | |||
| 768 | i2c_hid_dbg(ihid, "%s, ihid->hdesc_buffer: %*ph\n", | ||
| 769 | __func__, 4, ihid->hdesc_buffer); | ||
| 770 | |||
| 771 | if (ret) { | ||
| 772 | dev_err(&client->dev, | ||
| 773 | "unable to fetch the size of HID descriptor (ret=%d)\n", | ||
| 774 | ret); | ||
| 775 | return -ENODEV; | ||
| 776 | } | ||
| 777 | |||
| 778 | dsize = le16_to_cpu(hdesc->wHIDDescLength); | ||
| 779 | /* | ||
| 780 | * the size of the HID descriptor should at least contain | ||
| 781 | * its size and the bcdVersion (4 bytes), and should not be greater | ||
| 782 | * than sizeof(struct i2c_hid_desc) as we directly fill this struct | ||
| 783 | * through i2c_hid_command. | ||
| 784 | */ | ||
| 785 | if (dsize < 4 || dsize > sizeof(struct i2c_hid_desc)) { | ||
| 786 | dev_err(&client->dev, "weird size of HID descriptor (%u)\n", | ||
| 787 | dsize); | ||
| 788 | return -ENODEV; | ||
| 789 | } | ||
| 790 | |||
| 791 | /* check bcdVersion == 1.0 */ | ||
| 792 | if (le16_to_cpu(hdesc->bcdVersion) != 0x0100) { | ||
| 793 | dev_err(&client->dev, | ||
| 794 | "unexpected HID descriptor bcdVersion (0x%04hx)\n", | ||
| 795 | le16_to_cpu(hdesc->bcdVersion)); | ||
| 796 | return -ENODEV; | ||
| 797 | } | ||
| 798 | |||
| 799 | i2c_hid_dbg(ihid, "Fetching the HID descriptor\n"); | ||
| 800 | |||
| 801 | ret = i2c_hid_command(client, &hid_descr_cmd, ihid->hdesc_buffer, | ||
| 802 | dsize); | ||
| 803 | if (ret) { | ||
| 804 | dev_err(&client->dev, "hid_descr_cmd Fail\n"); | ||
| 805 | return -ENODEV; | ||
| 806 | } | ||
| 807 | |||
| 808 | i2c_hid_dbg(ihid, "HID Descriptor: %*ph\n", dsize, ihid->hdesc_buffer); | ||
| 809 | |||
| 810 | return 0; | ||
| 811 | } | ||
| 812 | |||
| 813 | static int __devinit i2c_hid_probe(struct i2c_client *client, | ||
| 814 | const struct i2c_device_id *dev_id) | ||
| 815 | { | ||
| 816 | int ret; | ||
| 817 | struct i2c_hid *ihid; | ||
| 818 | struct hid_device *hid; | ||
| 819 | __u16 hidRegister; | ||
| 820 | struct i2c_hid_platform_data *platform_data = client->dev.platform_data; | ||
| 821 | |||
| 822 | dbg_hid("HID probe called for i2c 0x%02x\n", client->addr); | ||
| 823 | |||
| 824 | if (!platform_data) { | ||
| 825 | dev_err(&client->dev, "HID register address not provided\n"); | ||
| 826 | return -EINVAL; | ||
| 827 | } | ||
| 828 | |||
| 829 | if (!client->irq) { | ||
| 830 | dev_err(&client->dev, | ||
| 831 | "HID over i2c has not been provided an Int IRQ\n"); | ||
| 832 | return -EINVAL; | ||
| 833 | } | ||
| 834 | |||
| 835 | ihid = kzalloc(sizeof(struct i2c_hid), GFP_KERNEL); | ||
| 836 | if (!ihid) | ||
| 837 | return -ENOMEM; | ||
| 838 | |||
| 839 | i2c_set_clientdata(client, ihid); | ||
| 840 | |||
| 841 | ihid->client = client; | ||
| 842 | |||
| 843 | hidRegister = platform_data->hid_descriptor_address; | ||
| 844 | ihid->wHIDDescRegister = cpu_to_le16(hidRegister); | ||
| 845 | |||
| 846 | init_waitqueue_head(&ihid->wait); | ||
| 847 | |||
| 848 | /* we need to allocate the command buffer without knowing the maximum | ||
| 849 | * size of the reports. Let's use HID_MIN_BUFFER_SIZE, then we do the | ||
| 850 | * real computation later. */ | ||
| 851 | ret = i2c_hid_alloc_buffers(ihid, HID_MIN_BUFFER_SIZE); | ||
| 852 | if (ret < 0) | ||
| 853 | goto err; | ||
| 854 | |||
| 855 | ret = i2c_hid_fetch_hid_descriptor(ihid); | ||
| 856 | if (ret < 0) | ||
| 857 | goto err; | ||
| 858 | |||
| 859 | ret = i2c_hid_init_irq(client); | ||
| 860 | if (ret < 0) | ||
| 861 | goto err; | ||
| 862 | |||
| 863 | hid = hid_allocate_device(); | ||
| 864 | if (IS_ERR(hid)) { | ||
| 865 | ret = PTR_ERR(hid); | ||
| 866 | goto err_irq; | ||
| 867 | } | ||
| 868 | |||
| 869 | ihid->hid = hid; | ||
| 870 | |||
| 871 | hid->driver_data = client; | ||
| 872 | hid->ll_driver = &i2c_hid_ll_driver; | ||
| 873 | hid->hid_get_raw_report = i2c_hid_get_raw_report; | ||
| 874 | hid->hid_output_raw_report = i2c_hid_output_raw_report; | ||
| 875 | hid->dev.parent = &client->dev; | ||
| 876 | hid->bus = BUS_I2C; | ||
| 877 | hid->version = le16_to_cpu(ihid->hdesc.bcdVersion); | ||
| 878 | hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID); | ||
| 879 | hid->product = le16_to_cpu(ihid->hdesc.wProductID); | ||
| 880 | |||
| 881 | snprintf(hid->name, sizeof(hid->name), "%s %04hX:%04hX", | ||
| 882 | client->name, hid->vendor, hid->product); | ||
| 883 | |||
| 884 | ret = hid_add_device(hid); | ||
| 885 | if (ret) { | ||
| 886 | if (ret != -ENODEV) | ||
| 887 | hid_err(client, "can't add hid device: %d\n", ret); | ||
| 888 | goto err_mem_free; | ||
| 889 | } | ||
| 890 | |||
| 891 | return 0; | ||
| 892 | |||
| 893 | err_mem_free: | ||
| 894 | hid_destroy_device(hid); | ||
| 895 | |||
| 896 | err_irq: | ||
| 897 | free_irq(client->irq, ihid); | ||
| 898 | |||
| 899 | err: | ||
| 900 | i2c_hid_free_buffers(ihid); | ||
| 901 | kfree(ihid); | ||
| 902 | return ret; | ||
| 903 | } | ||
| 904 | |||
| 905 | static int __devexit i2c_hid_remove(struct i2c_client *client) | ||
| 906 | { | ||
| 907 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
| 908 | struct hid_device *hid; | ||
| 909 | |||
| 910 | hid = ihid->hid; | ||
| 911 | hid_destroy_device(hid); | ||
| 912 | |||
| 913 | free_irq(client->irq, ihid); | ||
| 914 | |||
| 915 | if (ihid->bufsize) | ||
| 916 | i2c_hid_free_buffers(ihid); | ||
| 917 | |||
| 918 | kfree(ihid); | ||
| 919 | |||
| 920 | return 0; | ||
| 921 | } | ||
| 922 | |||
| 923 | #ifdef CONFIG_PM_SLEEP | ||
| 924 | static int i2c_hid_suspend(struct device *dev) | ||
| 925 | { | ||
| 926 | struct i2c_client *client = to_i2c_client(dev); | ||
| 927 | |||
| 928 | if (device_may_wakeup(&client->dev)) | ||
| 929 | enable_irq_wake(client->irq); | ||
| 930 | |||
| 931 | /* Save some power */ | ||
| 932 | i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); | ||
| 933 | |||
| 934 | return 0; | ||
| 935 | } | ||
| 936 | |||
| 937 | static int i2c_hid_resume(struct device *dev) | ||
| 938 | { | ||
| 939 | int ret; | ||
| 940 | struct i2c_client *client = to_i2c_client(dev); | ||
| 941 | |||
| 942 | ret = i2c_hid_hwreset(client); | ||
| 943 | if (ret) | ||
| 944 | return ret; | ||
| 945 | |||
| 946 | if (device_may_wakeup(&client->dev)) | ||
| 947 | disable_irq_wake(client->irq); | ||
| 948 | |||
| 949 | return 0; | ||
| 950 | } | ||
| 951 | #endif | ||
| 952 | |||
| 953 | static SIMPLE_DEV_PM_OPS(i2c_hid_pm, i2c_hid_suspend, i2c_hid_resume); | ||
| 954 | |||
| 955 | static const struct i2c_device_id i2c_hid_id_table[] = { | ||
| 956 | { "hid", 0 }, | ||
| 957 | { }, | ||
| 958 | }; | ||
| 959 | MODULE_DEVICE_TABLE(i2c, i2c_hid_id_table); | ||
| 960 | |||
| 961 | |||
| 962 | static struct i2c_driver i2c_hid_driver = { | ||
| 963 | .driver = { | ||
| 964 | .name = "i2c_hid", | ||
| 965 | .owner = THIS_MODULE, | ||
| 966 | .pm = &i2c_hid_pm, | ||
| 967 | }, | ||
| 968 | |||
| 969 | .probe = i2c_hid_probe, | ||
| 970 | .remove = __devexit_p(i2c_hid_remove), | ||
| 971 | |||
| 972 | .id_table = i2c_hid_id_table, | ||
| 973 | }; | ||
| 974 | |||
| 975 | module_i2c_driver(i2c_hid_driver); | ||
| 976 | |||
| 977 | MODULE_DESCRIPTION("HID over I2C core driver"); | ||
| 978 | MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>"); | ||
| 979 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 11c7932dc7e6..ac9e35228254 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
| @@ -72,6 +72,7 @@ static const struct hid_blacklist { | |||
| 72 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, | 72 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
| 73 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, | 73 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, |
| 74 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, | 74 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, |
| 75 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, | ||
| 75 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, | 76 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, |
| 76 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, | 77 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, |
| 77 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, | 78 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, |
| @@ -79,9 +80,11 @@ static const struct hid_blacklist { | |||
| 79 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET }, | 80 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET }, |
| 80 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, | 81 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, |
| 81 | { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, | 82 | { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, |
| 83 | { USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET }, | ||
| 82 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, | 84 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, |
| 83 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, | 85 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, |
| 84 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, | 86 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, |
| 87 | { USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN, HID_QUIRK_NOGET }, | ||
| 85 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, | 88 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, |
| 86 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, | 89 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, |
| 87 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, | 90 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 14599e256791..87bd64959a91 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
| @@ -361,10 +361,6 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun | |||
| 361 | prepare_to_wait(&list->hiddev->wait, &wait, TASK_INTERRUPTIBLE); | 361 | prepare_to_wait(&list->hiddev->wait, &wait, TASK_INTERRUPTIBLE); |
| 362 | 362 | ||
| 363 | while (list->head == list->tail) { | 363 | while (list->head == list->tail) { |
| 364 | if (file->f_flags & O_NONBLOCK) { | ||
| 365 | retval = -EAGAIN; | ||
| 366 | break; | ||
| 367 | } | ||
| 368 | if (signal_pending(current)) { | 364 | if (signal_pending(current)) { |
| 369 | retval = -ERESTARTSYS; | 365 | retval = -ERESTARTSYS; |
| 370 | break; | 366 | break; |
| @@ -373,6 +369,10 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun | |||
| 373 | retval = -EIO; | 369 | retval = -EIO; |
| 374 | break; | 370 | break; |
| 375 | } | 371 | } |
| 372 | if (file->f_flags & O_NONBLOCK) { | ||
| 373 | retval = -EAGAIN; | ||
| 374 | break; | ||
| 375 | } | ||
| 376 | 376 | ||
| 377 | /* let O_NONBLOCK tasks run */ | 377 | /* let O_NONBLOCK tasks run */ |
| 378 | mutex_unlock(&list->thread_lock); | 378 | mutex_unlock(&list->thread_lock); |
| @@ -625,7 +625,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 625 | break; | 625 | break; |
| 626 | 626 | ||
| 627 | case HIDIOCAPPLICATION: | 627 | case HIDIOCAPPLICATION: |
| 628 | if (arg < 0 || arg >= hid->maxapplication) | 628 | if (arg >= hid->maxapplication) |
| 629 | break; | 629 | break; |
| 630 | 630 | ||
| 631 | for (i = 0; i < hid->maxcollection; i++) | 631 | for (i = 0; i < hid->maxcollection; i++) |
diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c index 5f097f309b9f..7fa5b24b16db 100644 --- a/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c | |||
| @@ -169,7 +169,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev) | |||
| 169 | mux->busses = devm_kzalloc(&pdev->dev, | 169 | mux->busses = devm_kzalloc(&pdev->dev, |
| 170 | sizeof(mux->busses) * mux->pdata->bus_count, | 170 | sizeof(mux->busses) * mux->pdata->bus_count, |
| 171 | GFP_KERNEL); | 171 | GFP_KERNEL); |
| 172 | if (!mux->states) { | 172 | if (!mux->busses) { |
| 173 | dev_err(&pdev->dev, "Cannot allocate busses\n"); | 173 | dev_err(&pdev->dev, "Cannot allocate busses\n"); |
| 174 | ret = -ENOMEM; | 174 | ret = -ENOMEM; |
| 175 | goto err; | 175 | goto err; |
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig index a233ed53913a..86cd75a0e84d 100644 --- a/drivers/isdn/Kconfig +++ b/drivers/isdn/Kconfig | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | menuconfig ISDN | 5 | menuconfig ISDN |
| 6 | bool "ISDN support" | 6 | bool "ISDN support" |
| 7 | depends on NET | 7 | depends on NET && NETDEVICES |
| 8 | depends on !S390 && !UML | 8 | depends on !S390 && !UML |
| 9 | ---help--- | 9 | ---help--- |
| 10 | ISDN ("Integrated Services Digital Network", called RNIS in France) | 10 | ISDN ("Integrated Services Digital Network", called RNIS in France) |
diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig index 2302fbe70ac6..9c6650ea848e 100644 --- a/drivers/isdn/i4l/Kconfig +++ b/drivers/isdn/i4l/Kconfig | |||
| @@ -6,7 +6,7 @@ if ISDN_I4L | |||
| 6 | 6 | ||
| 7 | config ISDN_PPP | 7 | config ISDN_PPP |
| 8 | bool "Support synchronous PPP" | 8 | bool "Support synchronous PPP" |
| 9 | depends on INET && NETDEVICES | 9 | depends on INET |
| 10 | select SLHC | 10 | select SLHC |
| 11 | help | 11 | help |
| 12 | Over digital connections such as ISDN, there is no need to | 12 | Over digital connections such as ISDN, there is no need to |
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 8c610fa6782b..e2a945ee9f05 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
| @@ -1312,7 +1312,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) | |||
| 1312 | } else | 1312 | } else |
| 1313 | return -EINVAL; | 1313 | return -EINVAL; |
| 1314 | break; | 1314 | break; |
| 1315 | #ifdef CONFIG_NETDEVICES | ||
| 1316 | case IIOCNETGPN: | 1315 | case IIOCNETGPN: |
| 1317 | /* Get peer phone number of a connected | 1316 | /* Get peer phone number of a connected |
| 1318 | * isdn network interface */ | 1317 | * isdn network interface */ |
| @@ -1322,7 +1321,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) | |||
| 1322 | return isdn_net_getpeer(&phone, argp); | 1321 | return isdn_net_getpeer(&phone, argp); |
| 1323 | } else | 1322 | } else |
| 1324 | return -EINVAL; | 1323 | return -EINVAL; |
| 1325 | #endif | ||
| 1326 | default: | 1324 | default: |
| 1327 | return -EINVAL; | 1325 | return -EINVAL; |
| 1328 | } | 1326 | } |
| @@ -1352,7 +1350,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) | |||
| 1352 | case IIOCNETLCR: | 1350 | case IIOCNETLCR: |
| 1353 | printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n"); | 1351 | printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n"); |
| 1354 | return -ENODEV; | 1352 | return -ENODEV; |
| 1355 | #ifdef CONFIG_NETDEVICES | ||
| 1356 | case IIOCNETAIF: | 1353 | case IIOCNETAIF: |
| 1357 | /* Add a network-interface */ | 1354 | /* Add a network-interface */ |
| 1358 | if (arg) { | 1355 | if (arg) { |
| @@ -1491,7 +1488,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) | |||
| 1491 | return -EFAULT; | 1488 | return -EFAULT; |
| 1492 | return isdn_net_force_hangup(name); | 1489 | return isdn_net_force_hangup(name); |
| 1493 | break; | 1490 | break; |
| 1494 | #endif /* CONFIG_NETDEVICES */ | ||
| 1495 | case IIOCSETVER: | 1491 | case IIOCSETVER: |
| 1496 | dev->net_verbose = arg; | 1492 | dev->net_verbose = arg; |
| 1497 | printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose); | 1493 | printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose); |
diff --git a/drivers/leds/ledtrig-cpu.c b/drivers/leds/ledtrig-cpu.c index b312056da14d..4239b3955ff0 100644 --- a/drivers/leds/ledtrig-cpu.c +++ b/drivers/leds/ledtrig-cpu.c | |||
| @@ -33,8 +33,6 @@ | |||
| 33 | struct led_trigger_cpu { | 33 | struct led_trigger_cpu { |
| 34 | char name[MAX_NAME_LEN]; | 34 | char name[MAX_NAME_LEN]; |
| 35 | struct led_trigger *_trig; | 35 | struct led_trigger *_trig; |
| 36 | struct mutex lock; | ||
| 37 | int lock_is_inited; | ||
| 38 | }; | 36 | }; |
| 39 | 37 | ||
| 40 | static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); | 38 | static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); |
| @@ -50,12 +48,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) | |||
| 50 | { | 48 | { |
| 51 | struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig); | 49 | struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig); |
| 52 | 50 | ||
| 53 | /* mutex lock should be initialized before calling mutex_call() */ | ||
| 54 | if (!trig->lock_is_inited) | ||
| 55 | return; | ||
| 56 | |||
| 57 | mutex_lock(&trig->lock); | ||
| 58 | |||
| 59 | /* Locate the correct CPU LED */ | 51 | /* Locate the correct CPU LED */ |
| 60 | switch (ledevt) { | 52 | switch (ledevt) { |
| 61 | case CPU_LED_IDLE_END: | 53 | case CPU_LED_IDLE_END: |
| @@ -75,8 +67,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) | |||
| 75 | /* Will leave the LED as it is */ | 67 | /* Will leave the LED as it is */ |
| 76 | break; | 68 | break; |
| 77 | } | 69 | } |
| 78 | |||
| 79 | mutex_unlock(&trig->lock); | ||
| 80 | } | 70 | } |
| 81 | EXPORT_SYMBOL(ledtrig_cpu); | 71 | EXPORT_SYMBOL(ledtrig_cpu); |
| 82 | 72 | ||
| @@ -117,14 +107,9 @@ static int __init ledtrig_cpu_init(void) | |||
| 117 | for_each_possible_cpu(cpu) { | 107 | for_each_possible_cpu(cpu) { |
| 118 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); | 108 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); |
| 119 | 109 | ||
| 120 | mutex_init(&trig->lock); | ||
| 121 | |||
| 122 | snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); | 110 | snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); |
| 123 | 111 | ||
| 124 | mutex_lock(&trig->lock); | ||
| 125 | led_trigger_register_simple(trig->name, &trig->_trig); | 112 | led_trigger_register_simple(trig->name, &trig->_trig); |
| 126 | trig->lock_is_inited = 1; | ||
| 127 | mutex_unlock(&trig->lock); | ||
| 128 | } | 113 | } |
| 129 | 114 | ||
| 130 | register_syscore_ops(&ledtrig_cpu_syscore_ops); | 115 | register_syscore_ops(&ledtrig_cpu_syscore_ops); |
| @@ -142,15 +127,9 @@ static void __exit ledtrig_cpu_exit(void) | |||
| 142 | for_each_possible_cpu(cpu) { | 127 | for_each_possible_cpu(cpu) { |
| 143 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); | 128 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); |
| 144 | 129 | ||
| 145 | mutex_lock(&trig->lock); | ||
| 146 | |||
| 147 | led_trigger_unregister_simple(trig->_trig); | 130 | led_trigger_unregister_simple(trig->_trig); |
| 148 | trig->_trig = NULL; | 131 | trig->_trig = NULL; |
| 149 | memset(trig->name, 0, MAX_NAME_LEN); | 132 | memset(trig->name, 0, MAX_NAME_LEN); |
| 150 | trig->lock_is_inited = 0; | ||
| 151 | |||
| 152 | mutex_unlock(&trig->lock); | ||
| 153 | mutex_destroy(&trig->lock); | ||
| 154 | } | 133 | } |
| 155 | 134 | ||
| 156 | unregister_syscore_ops(&ledtrig_cpu_syscore_ops); | 135 | unregister_syscore_ops(&ledtrig_cpu_syscore_ops); |
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index 660bbc528862..4d50da618166 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c | |||
| @@ -208,7 +208,7 @@ static unsigned long exynos5250_dwmmc_caps[4] = { | |||
| 208 | MMC_CAP_CMD23, | 208 | MMC_CAP_CMD23, |
| 209 | }; | 209 | }; |
| 210 | 210 | ||
| 211 | static struct dw_mci_drv_data exynos5250_drv_data = { | 211 | static const struct dw_mci_drv_data exynos5250_drv_data = { |
| 212 | .caps = exynos5250_dwmmc_caps, | 212 | .caps = exynos5250_dwmmc_caps, |
| 213 | .init = dw_mci_exynos_priv_init, | 213 | .init = dw_mci_exynos_priv_init, |
| 214 | .setup_clock = dw_mci_exynos_setup_clock, | 214 | .setup_clock = dw_mci_exynos_setup_clock, |
| @@ -220,14 +220,14 @@ static struct dw_mci_drv_data exynos5250_drv_data = { | |||
| 220 | 220 | ||
| 221 | static const struct of_device_id dw_mci_exynos_match[] = { | 221 | static const struct of_device_id dw_mci_exynos_match[] = { |
| 222 | { .compatible = "samsung,exynos5250-dw-mshc", | 222 | { .compatible = "samsung,exynos5250-dw-mshc", |
| 223 | .data = (void *)&exynos5250_drv_data, }, | 223 | .data = &exynos5250_drv_data, }, |
| 224 | {}, | 224 | {}, |
| 225 | }; | 225 | }; |
| 226 | MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); | 226 | MODULE_DEVICE_TABLE(of, dw_mci_exynos_match); |
| 227 | 227 | ||
| 228 | int dw_mci_exynos_probe(struct platform_device *pdev) | 228 | int dw_mci_exynos_probe(struct platform_device *pdev) |
| 229 | { | 229 | { |
| 230 | struct dw_mci_drv_data *drv_data; | 230 | const struct dw_mci_drv_data *drv_data; |
| 231 | const struct of_device_id *match; | 231 | const struct of_device_id *match; |
| 232 | 232 | ||
| 233 | match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node); | 233 | match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node); |
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index c960ca7ffbe6..917936bee5d5 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | #include "dw_mmc.h" | 24 | #include "dw_mmc.h" |
| 25 | 25 | ||
| 26 | int dw_mci_pltfm_register(struct platform_device *pdev, | 26 | int dw_mci_pltfm_register(struct platform_device *pdev, |
| 27 | struct dw_mci_drv_data *drv_data) | 27 | const struct dw_mci_drv_data *drv_data) |
| 28 | { | 28 | { |
| 29 | struct dw_mci *host; | 29 | struct dw_mci *host; |
| 30 | struct resource *regs; | 30 | struct resource *regs; |
| @@ -50,8 +50,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev, | |||
| 50 | if (!host->regs) | 50 | if (!host->regs) |
| 51 | return -ENOMEM; | 51 | return -ENOMEM; |
| 52 | 52 | ||
| 53 | if (host->drv_data->init) { | 53 | if (drv_data && drv_data->init) { |
| 54 | ret = host->drv_data->init(host); | 54 | ret = drv_data->init(host); |
| 55 | if (ret) | 55 | if (ret) |
| 56 | return ret; | 56 | return ret; |
| 57 | } | 57 | } |
diff --git a/drivers/mmc/host/dw_mmc-pltfm.h b/drivers/mmc/host/dw_mmc-pltfm.h index 301f24541fc2..2ac37b81de4d 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.h +++ b/drivers/mmc/host/dw_mmc-pltfm.h | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #define _DW_MMC_PLTFM_H_ | 13 | #define _DW_MMC_PLTFM_H_ |
| 14 | 14 | ||
| 15 | extern int dw_mci_pltfm_register(struct platform_device *pdev, | 15 | extern int dw_mci_pltfm_register(struct platform_device *pdev, |
| 16 | struct dw_mci_drv_data *drv_data); | 16 | const struct dw_mci_drv_data *drv_data); |
| 17 | extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev); | 17 | extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev); |
| 18 | extern const struct dev_pm_ops dw_mci_pltfm_pmops; | 18 | extern const struct dev_pm_ops dw_mci_pltfm_pmops; |
| 19 | 19 | ||
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index c2828f35c3b8..c0667c8af2bd 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
| @@ -232,6 +232,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) | |||
| 232 | { | 232 | { |
| 233 | struct mmc_data *data; | 233 | struct mmc_data *data; |
| 234 | struct dw_mci_slot *slot = mmc_priv(mmc); | 234 | struct dw_mci_slot *slot = mmc_priv(mmc); |
| 235 | struct dw_mci_drv_data *drv_data = slot->host->drv_data; | ||
| 235 | u32 cmdr; | 236 | u32 cmdr; |
| 236 | cmd->error = -EINPROGRESS; | 237 | cmd->error = -EINPROGRESS; |
| 237 | 238 | ||
| @@ -261,8 +262,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) | |||
| 261 | cmdr |= SDMMC_CMD_DAT_WR; | 262 | cmdr |= SDMMC_CMD_DAT_WR; |
| 262 | } | 263 | } |
| 263 | 264 | ||
| 264 | if (slot->host->drv_data->prepare_command) | 265 | if (drv_data && drv_data->prepare_command) |
| 265 | slot->host->drv_data->prepare_command(slot->host, &cmdr); | 266 | drv_data->prepare_command(slot->host, &cmdr); |
| 266 | 267 | ||
| 267 | return cmdr; | 268 | return cmdr; |
| 268 | } | 269 | } |
| @@ -434,7 +435,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) | |||
| 434 | return 0; | 435 | return 0; |
| 435 | } | 436 | } |
| 436 | 437 | ||
| 437 | static struct dw_mci_dma_ops dw_mci_idmac_ops = { | 438 | static const struct dw_mci_dma_ops dw_mci_idmac_ops = { |
| 438 | .init = dw_mci_idmac_init, | 439 | .init = dw_mci_idmac_init, |
| 439 | .start = dw_mci_idmac_start_dma, | 440 | .start = dw_mci_idmac_start_dma, |
| 440 | .stop = dw_mci_idmac_stop_dma, | 441 | .stop = dw_mci_idmac_stop_dma, |
| @@ -772,6 +773,7 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 772 | static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 773 | static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
| 773 | { | 774 | { |
| 774 | struct dw_mci_slot *slot = mmc_priv(mmc); | 775 | struct dw_mci_slot *slot = mmc_priv(mmc); |
| 776 | struct dw_mci_drv_data *drv_data = slot->host->drv_data; | ||
| 775 | u32 regs; | 777 | u32 regs; |
| 776 | 778 | ||
| 777 | /* set default 1 bit mode */ | 779 | /* set default 1 bit mode */ |
| @@ -807,8 +809,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 807 | slot->clock = ios->clock; | 809 | slot->clock = ios->clock; |
| 808 | } | 810 | } |
| 809 | 811 | ||
| 810 | if (slot->host->drv_data->set_ios) | 812 | if (drv_data && drv_data->set_ios) |
| 811 | slot->host->drv_data->set_ios(slot->host, ios); | 813 | drv_data->set_ios(slot->host, ios); |
| 812 | 814 | ||
| 813 | switch (ios->power_mode) { | 815 | switch (ios->power_mode) { |
| 814 | case MMC_POWER_UP: | 816 | case MMC_POWER_UP: |
| @@ -1815,6 +1817,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
| 1815 | { | 1817 | { |
| 1816 | struct mmc_host *mmc; | 1818 | struct mmc_host *mmc; |
| 1817 | struct dw_mci_slot *slot; | 1819 | struct dw_mci_slot *slot; |
| 1820 | struct dw_mci_drv_data *drv_data = host->drv_data; | ||
| 1818 | int ctrl_id, ret; | 1821 | int ctrl_id, ret; |
| 1819 | u8 bus_width; | 1822 | u8 bus_width; |
| 1820 | 1823 | ||
| @@ -1854,8 +1857,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
| 1854 | } else { | 1857 | } else { |
| 1855 | ctrl_id = to_platform_device(host->dev)->id; | 1858 | ctrl_id = to_platform_device(host->dev)->id; |
| 1856 | } | 1859 | } |
| 1857 | if (host->drv_data && host->drv_data->caps) | 1860 | if (drv_data && drv_data->caps) |
| 1858 | mmc->caps |= host->drv_data->caps[ctrl_id]; | 1861 | mmc->caps |= drv_data->caps[ctrl_id]; |
| 1859 | 1862 | ||
| 1860 | if (host->pdata->caps2) | 1863 | if (host->pdata->caps2) |
| 1861 | mmc->caps2 = host->pdata->caps2; | 1864 | mmc->caps2 = host->pdata->caps2; |
| @@ -1867,10 +1870,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
| 1867 | else | 1870 | else |
| 1868 | bus_width = 1; | 1871 | bus_width = 1; |
| 1869 | 1872 | ||
| 1870 | if (host->drv_data->setup_bus) { | 1873 | if (drv_data && drv_data->setup_bus) { |
| 1871 | struct device_node *slot_np; | 1874 | struct device_node *slot_np; |
| 1872 | slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); | 1875 | slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); |
| 1873 | ret = host->drv_data->setup_bus(host, slot_np, bus_width); | 1876 | ret = drv_data->setup_bus(host, slot_np, bus_width); |
| 1874 | if (ret) | 1877 | if (ret) |
| 1875 | goto err_setup_bus; | 1878 | goto err_setup_bus; |
| 1876 | } | 1879 | } |
| @@ -1968,7 +1971,7 @@ static void dw_mci_init_dma(struct dw_mci *host) | |||
| 1968 | /* Determine which DMA interface to use */ | 1971 | /* Determine which DMA interface to use */ |
| 1969 | #ifdef CONFIG_MMC_DW_IDMAC | 1972 | #ifdef CONFIG_MMC_DW_IDMAC |
| 1970 | host->dma_ops = &dw_mci_idmac_ops; | 1973 | host->dma_ops = &dw_mci_idmac_ops; |
| 1971 | dev_info(&host->dev, "Using internal DMA controller.\n"); | 1974 | dev_info(host->dev, "Using internal DMA controller.\n"); |
| 1972 | #endif | 1975 | #endif |
| 1973 | 1976 | ||
| 1974 | if (!host->dma_ops) | 1977 | if (!host->dma_ops) |
| @@ -2035,6 +2038,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
| 2035 | struct dw_mci_board *pdata; | 2038 | struct dw_mci_board *pdata; |
| 2036 | struct device *dev = host->dev; | 2039 | struct device *dev = host->dev; |
| 2037 | struct device_node *np = dev->of_node; | 2040 | struct device_node *np = dev->of_node; |
| 2041 | struct dw_mci_drv_data *drv_data = host->drv_data; | ||
| 2038 | int idx, ret; | 2042 | int idx, ret; |
| 2039 | 2043 | ||
| 2040 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 2044 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
| @@ -2062,8 +2066,8 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
| 2062 | 2066 | ||
| 2063 | of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); | 2067 | of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); |
| 2064 | 2068 | ||
| 2065 | if (host->drv_data->parse_dt) { | 2069 | if (drv_data && drv_data->parse_dt) { |
| 2066 | ret = host->drv_data->parse_dt(host); | 2070 | ret = drv_data->parse_dt(host); |
| 2067 | if (ret) | 2071 | if (ret) |
| 2068 | return ERR_PTR(ret); | 2072 | return ERR_PTR(ret); |
| 2069 | } | 2073 | } |
| @@ -2080,6 +2084,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
| 2080 | 2084 | ||
| 2081 | int dw_mci_probe(struct dw_mci *host) | 2085 | int dw_mci_probe(struct dw_mci *host) |
| 2082 | { | 2086 | { |
| 2087 | struct dw_mci_drv_data *drv_data = host->drv_data; | ||
| 2083 | int width, i, ret = 0; | 2088 | int width, i, ret = 0; |
| 2084 | u32 fifo_size; | 2089 | u32 fifo_size; |
| 2085 | int init_slots = 0; | 2090 | int init_slots = 0; |
| @@ -2127,8 +2132,8 @@ int dw_mci_probe(struct dw_mci *host) | |||
| 2127 | else | 2132 | else |
| 2128 | host->bus_hz = clk_get_rate(host->ciu_clk); | 2133 | host->bus_hz = clk_get_rate(host->ciu_clk); |
| 2129 | 2134 | ||
| 2130 | if (host->drv_data->setup_clock) { | 2135 | if (drv_data && drv_data->setup_clock) { |
| 2131 | ret = host->drv_data->setup_clock(host); | 2136 | ret = drv_data->setup_clock(host); |
| 2132 | if (ret) { | 2137 | if (ret) { |
| 2133 | dev_err(host->dev, | 2138 | dev_err(host->dev, |
| 2134 | "implementation specific clock setup failed\n"); | 2139 | "implementation specific clock setup failed\n"); |
| @@ -2228,6 +2233,21 @@ int dw_mci_probe(struct dw_mci *host) | |||
| 2228 | else | 2233 | else |
| 2229 | host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; | 2234 | host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; |
| 2230 | 2235 | ||
| 2236 | /* | ||
| 2237 | * Enable interrupts for command done, data over, data empty, card det, | ||
| 2238 | * receive ready and error such as transmit, receive timeout, crc error | ||
| 2239 | */ | ||
| 2240 | mci_writel(host, RINTSTS, 0xFFFFFFFF); | ||
| 2241 | mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | | ||
| 2242 | SDMMC_INT_TXDR | SDMMC_INT_RXDR | | ||
| 2243 | DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); | ||
| 2244 | mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ | ||
| 2245 | |||
| 2246 | dev_info(host->dev, "DW MMC controller at irq %d, " | ||
| 2247 | "%d bit host data width, " | ||
| 2248 | "%u deep fifo\n", | ||
| 2249 | host->irq, width, fifo_size); | ||
| 2250 | |||
| 2231 | /* We need at least one slot to succeed */ | 2251 | /* We need at least one slot to succeed */ |
| 2232 | for (i = 0; i < host->num_slots; i++) { | 2252 | for (i = 0; i < host->num_slots; i++) { |
| 2233 | ret = dw_mci_init_slot(host, i); | 2253 | ret = dw_mci_init_slot(host, i); |
| @@ -2257,20 +2277,6 @@ int dw_mci_probe(struct dw_mci *host) | |||
| 2257 | else | 2277 | else |
| 2258 | host->data_offset = DATA_240A_OFFSET; | 2278 | host->data_offset = DATA_240A_OFFSET; |
| 2259 | 2279 | ||
| 2260 | /* | ||
| 2261 | * Enable interrupts for command done, data over, data empty, card det, | ||
| 2262 | * receive ready and error such as transmit, receive timeout, crc error | ||
| 2263 | */ | ||
| 2264 | mci_writel(host, RINTSTS, 0xFFFFFFFF); | ||
| 2265 | mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | | ||
| 2266 | SDMMC_INT_TXDR | SDMMC_INT_RXDR | | ||
| 2267 | DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); | ||
| 2268 | mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ | ||
| 2269 | |||
| 2270 | dev_info(host->dev, "DW MMC controller at irq %d, " | ||
| 2271 | "%d bit host data width, " | ||
| 2272 | "%u deep fifo\n", | ||
| 2273 | host->irq, width, fifo_size); | ||
| 2274 | if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) | 2280 | if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) |
| 2275 | dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); | 2281 | dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); |
| 2276 | 2282 | ||
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 565c2e4fac75..6290b7f1ccfe 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
| @@ -1134,4 +1134,4 @@ module_platform_driver(mxcmci_driver); | |||
| 1134 | MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); | 1134 | MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); |
| 1135 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); | 1135 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); |
| 1136 | MODULE_LICENSE("GPL"); | 1136 | MODULE_LICENSE("GPL"); |
| 1137 | MODULE_ALIAS("platform:imx-mmc"); | 1137 | MODULE_ALIAS("platform:mxc-mmc"); |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 54bfd0cc106b..fedd258cc4ea 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
| @@ -178,7 +178,8 @@ struct omap_hsmmc_host { | |||
| 178 | 178 | ||
| 179 | static int omap_hsmmc_card_detect(struct device *dev, int slot) | 179 | static int omap_hsmmc_card_detect(struct device *dev, int slot) |
| 180 | { | 180 | { |
| 181 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 181 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
| 182 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
| 182 | 183 | ||
| 183 | /* NOTE: assumes card detect signal is active-low */ | 184 | /* NOTE: assumes card detect signal is active-low */ |
| 184 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | 185 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); |
| @@ -186,7 +187,8 @@ static int omap_hsmmc_card_detect(struct device *dev, int slot) | |||
| 186 | 187 | ||
| 187 | static int omap_hsmmc_get_wp(struct device *dev, int slot) | 188 | static int omap_hsmmc_get_wp(struct device *dev, int slot) |
| 188 | { | 189 | { |
| 189 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 190 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
| 191 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
| 190 | 192 | ||
| 191 | /* NOTE: assumes write protect signal is active-high */ | 193 | /* NOTE: assumes write protect signal is active-high */ |
| 192 | return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); | 194 | return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); |
| @@ -194,7 +196,8 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot) | |||
| 194 | 196 | ||
| 195 | static int omap_hsmmc_get_cover_state(struct device *dev, int slot) | 197 | static int omap_hsmmc_get_cover_state(struct device *dev, int slot) |
| 196 | { | 198 | { |
| 197 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 199 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
| 200 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
| 198 | 201 | ||
| 199 | /* NOTE: assumes card detect signal is active-low */ | 202 | /* NOTE: assumes card detect signal is active-low */ |
| 200 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); | 203 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); |
| @@ -204,7 +207,8 @@ static int omap_hsmmc_get_cover_state(struct device *dev, int slot) | |||
| 204 | 207 | ||
| 205 | static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) | 208 | static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) |
| 206 | { | 209 | { |
| 207 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 210 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
| 211 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
| 208 | 212 | ||
| 209 | disable_irq(mmc->slots[0].card_detect_irq); | 213 | disable_irq(mmc->slots[0].card_detect_irq); |
| 210 | return 0; | 214 | return 0; |
| @@ -212,7 +216,8 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) | |||
| 212 | 216 | ||
| 213 | static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) | 217 | static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) |
| 214 | { | 218 | { |
| 215 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 219 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
| 220 | struct omap_mmc_platform_data *mmc = host->pdata; | ||
| 216 | 221 | ||
| 217 | enable_irq(mmc->slots[0].card_detect_irq); | 222 | enable_irq(mmc->slots[0].card_detect_irq); |
| 218 | return 0; | 223 | return 0; |
| @@ -2009,9 +2014,9 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev) | |||
| 2009 | clk_put(host->dbclk); | 2014 | clk_put(host->dbclk); |
| 2010 | } | 2015 | } |
| 2011 | 2016 | ||
| 2012 | mmc_free_host(host->mmc); | 2017 | omap_hsmmc_gpio_free(host->pdata); |
| 2013 | iounmap(host->base); | 2018 | iounmap(host->base); |
| 2014 | omap_hsmmc_gpio_free(pdev->dev.platform_data); | 2019 | mmc_free_host(host->mmc); |
| 2015 | 2020 | ||
| 2016 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2021 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 2017 | if (res) | 2022 | if (res) |
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index 90140eb03e36..8fd50a211037 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include <linux/err.h> | ||
| 22 | #include <linux/io.h> | 23 | #include <linux/io.h> |
| 23 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
| 24 | #include <linux/err.h> | 25 | #include <linux/err.h> |
| @@ -84,30 +85,32 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev) | |||
| 84 | struct sdhci_dove_priv *priv; | 85 | struct sdhci_dove_priv *priv; |
| 85 | int ret; | 86 | int ret; |
| 86 | 87 | ||
| 87 | ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); | ||
| 88 | if (ret) | ||
| 89 | goto sdhci_dove_register_fail; | ||
| 90 | |||
| 91 | priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), | 88 | priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), |
| 92 | GFP_KERNEL); | 89 | GFP_KERNEL); |
| 93 | if (!priv) { | 90 | if (!priv) { |
| 94 | dev_err(&pdev->dev, "unable to allocate private data"); | 91 | dev_err(&pdev->dev, "unable to allocate private data"); |
| 95 | ret = -ENOMEM; | 92 | return -ENOMEM; |
| 96 | goto sdhci_dove_allocate_fail; | ||
| 97 | } | 93 | } |
| 98 | 94 | ||
| 95 | priv->clk = clk_get(&pdev->dev, NULL); | ||
| 96 | if (!IS_ERR(priv->clk)) | ||
| 97 | clk_prepare_enable(priv->clk); | ||
| 98 | |||
| 99 | ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); | ||
| 100 | if (ret) | ||
| 101 | goto sdhci_dove_register_fail; | ||
| 102 | |||
| 99 | host = platform_get_drvdata(pdev); | 103 | host = platform_get_drvdata(pdev); |
| 100 | pltfm_host = sdhci_priv(host); | 104 | pltfm_host = sdhci_priv(host); |
| 101 | pltfm_host->priv = priv; | 105 | pltfm_host->priv = priv; |
| 102 | 106 | ||
| 103 | priv->clk = clk_get(&pdev->dev, NULL); | ||
| 104 | if (!IS_ERR(priv->clk)) | ||
| 105 | clk_prepare_enable(priv->clk); | ||
| 106 | return 0; | 107 | return 0; |
| 107 | 108 | ||
| 108 | sdhci_dove_allocate_fail: | ||
| 109 | sdhci_pltfm_unregister(pdev); | ||
| 110 | sdhci_dove_register_fail: | 109 | sdhci_dove_register_fail: |
| 110 | if (!IS_ERR(priv->clk)) { | ||
| 111 | clk_disable_unprepare(priv->clk); | ||
| 112 | clk_put(priv->clk); | ||
| 113 | } | ||
| 111 | return ret; | 114 | return ret; |
| 112 | } | 115 | } |
| 113 | 116 | ||
| @@ -117,14 +120,13 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev) | |||
| 117 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 120 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 118 | struct sdhci_dove_priv *priv = pltfm_host->priv; | 121 | struct sdhci_dove_priv *priv = pltfm_host->priv; |
| 119 | 122 | ||
| 120 | if (priv->clk) { | 123 | sdhci_pltfm_unregister(pdev); |
| 121 | if (!IS_ERR(priv->clk)) { | 124 | |
| 122 | clk_disable_unprepare(priv->clk); | 125 | if (!IS_ERR(priv->clk)) { |
| 123 | clk_put(priv->clk); | 126 | clk_disable_unprepare(priv->clk); |
| 124 | } | 127 | clk_put(priv->clk); |
| 125 | devm_kfree(&pdev->dev, priv->clk); | ||
| 126 | } | 128 | } |
| 127 | return sdhci_pltfm_unregister(pdev); | 129 | return 0; |
| 128 | } | 130 | } |
| 129 | 131 | ||
| 130 | static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = { | 132 | static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = { |
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index ae5fcbfa1eef..63d219f57cae 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
| @@ -169,6 +169,16 @@ static void esdhc_of_resume(struct sdhci_host *host) | |||
| 169 | } | 169 | } |
| 170 | #endif | 170 | #endif |
| 171 | 171 | ||
| 172 | static void esdhc_of_platform_init(struct sdhci_host *host) | ||
| 173 | { | ||
| 174 | u32 vvn; | ||
| 175 | |||
| 176 | vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); | ||
| 177 | vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; | ||
| 178 | if (vvn == VENDOR_V_22) | ||
| 179 | host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; | ||
| 180 | } | ||
| 181 | |||
| 172 | static struct sdhci_ops sdhci_esdhc_ops = { | 182 | static struct sdhci_ops sdhci_esdhc_ops = { |
| 173 | .read_l = esdhc_readl, | 183 | .read_l = esdhc_readl, |
| 174 | .read_w = esdhc_readw, | 184 | .read_w = esdhc_readw, |
| @@ -180,6 +190,7 @@ static struct sdhci_ops sdhci_esdhc_ops = { | |||
| 180 | .enable_dma = esdhc_of_enable_dma, | 190 | .enable_dma = esdhc_of_enable_dma, |
| 181 | .get_max_clock = esdhc_of_get_max_clock, | 191 | .get_max_clock = esdhc_of_get_max_clock, |
| 182 | .get_min_clock = esdhc_of_get_min_clock, | 192 | .get_min_clock = esdhc_of_get_min_clock, |
| 193 | .platform_init = esdhc_of_platform_init, | ||
| 183 | #ifdef CONFIG_PM | 194 | #ifdef CONFIG_PM |
| 184 | .platform_suspend = esdhc_of_suspend, | 195 | .platform_suspend = esdhc_of_suspend, |
| 185 | .platform_resume = esdhc_of_resume, | 196 | .platform_resume = esdhc_of_resume, |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 4bb74b042a06..04936f353ced 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
| @@ -1196,7 +1196,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
| 1196 | return ERR_PTR(-ENODEV); | 1196 | return ERR_PTR(-ENODEV); |
| 1197 | } | 1197 | } |
| 1198 | 1198 | ||
| 1199 | if (pci_resource_len(pdev, bar) != 0x100) { | 1199 | if (pci_resource_len(pdev, bar) < 0x100) { |
| 1200 | dev_err(&pdev->dev, "Invalid iomem size. You may " | 1200 | dev_err(&pdev->dev, "Invalid iomem size. You may " |
| 1201 | "experience problems.\n"); | 1201 | "experience problems.\n"); |
| 1202 | } | 1202 | } |
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 65551a9709cc..27164457f861 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c | |||
| @@ -150,6 +150,13 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, | |||
| 150 | goto err_remap; | 150 | goto err_remap; |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | /* | ||
| 154 | * Some platforms need to probe the controller to be able to | ||
| 155 | * determine which caps should be used. | ||
| 156 | */ | ||
| 157 | if (host->ops && host->ops->platform_init) | ||
| 158 | host->ops->platform_init(host); | ||
| 159 | |||
| 153 | platform_set_drvdata(pdev, host); | 160 | platform_set_drvdata(pdev, host); |
| 154 | 161 | ||
| 155 | return host; | 162 | return host; |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 2903949594c6..a54dd5d7a5f9 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
| @@ -211,8 +211,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) | |||
| 211 | if (ourhost->cur_clk != best_src) { | 211 | if (ourhost->cur_clk != best_src) { |
| 212 | struct clk *clk = ourhost->clk_bus[best_src]; | 212 | struct clk *clk = ourhost->clk_bus[best_src]; |
| 213 | 213 | ||
| 214 | clk_enable(clk); | 214 | clk_prepare_enable(clk); |
| 215 | clk_disable(ourhost->clk_bus[ourhost->cur_clk]); | 215 | clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); |
| 216 | 216 | ||
| 217 | /* turn clock off to card before changing clock source */ | 217 | /* turn clock off to card before changing clock source */ |
| 218 | writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); | 218 | writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); |
| @@ -607,7 +607,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
| 607 | } | 607 | } |
| 608 | 608 | ||
| 609 | /* enable the local io clock and keep it running for the moment. */ | 609 | /* enable the local io clock and keep it running for the moment. */ |
| 610 | clk_enable(sc->clk_io); | 610 | clk_prepare_enable(sc->clk_io); |
| 611 | 611 | ||
| 612 | for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { | 612 | for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 613 | struct clk *clk; | 613 | struct clk *clk; |
| @@ -638,7 +638,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
| 638 | } | 638 | } |
| 639 | 639 | ||
| 640 | #ifndef CONFIG_PM_RUNTIME | 640 | #ifndef CONFIG_PM_RUNTIME |
| 641 | clk_enable(sc->clk_bus[sc->cur_clk]); | 641 | clk_prepare_enable(sc->clk_bus[sc->cur_clk]); |
| 642 | #endif | 642 | #endif |
| 643 | 643 | ||
| 644 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 644 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| @@ -747,13 +747,14 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
| 747 | sdhci_s3c_setup_card_detect_gpio(sc); | 747 | sdhci_s3c_setup_card_detect_gpio(sc); |
| 748 | 748 | ||
| 749 | #ifdef CONFIG_PM_RUNTIME | 749 | #ifdef CONFIG_PM_RUNTIME |
| 750 | clk_disable(sc->clk_io); | 750 | if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) |
| 751 | clk_disable_unprepare(sc->clk_io); | ||
| 751 | #endif | 752 | #endif |
| 752 | return 0; | 753 | return 0; |
| 753 | 754 | ||
| 754 | err_req_regs: | 755 | err_req_regs: |
| 755 | #ifndef CONFIG_PM_RUNTIME | 756 | #ifndef CONFIG_PM_RUNTIME |
| 756 | clk_disable(sc->clk_bus[sc->cur_clk]); | 757 | clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); |
| 757 | #endif | 758 | #endif |
| 758 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { | 759 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 759 | if (sc->clk_bus[ptr]) { | 760 | if (sc->clk_bus[ptr]) { |
| @@ -762,7 +763,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
| 762 | } | 763 | } |
| 763 | 764 | ||
| 764 | err_no_busclks: | 765 | err_no_busclks: |
| 765 | clk_disable(sc->clk_io); | 766 | clk_disable_unprepare(sc->clk_io); |
| 766 | clk_put(sc->clk_io); | 767 | clk_put(sc->clk_io); |
| 767 | 768 | ||
| 768 | err_io_clk: | 769 | err_io_clk: |
| @@ -794,7 +795,8 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) | |||
| 794 | gpio_free(sc->ext_cd_gpio); | 795 | gpio_free(sc->ext_cd_gpio); |
| 795 | 796 | ||
| 796 | #ifdef CONFIG_PM_RUNTIME | 797 | #ifdef CONFIG_PM_RUNTIME |
| 797 | clk_enable(sc->clk_io); | 798 | if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) |
| 799 | clk_prepare_enable(sc->clk_io); | ||
| 798 | #endif | 800 | #endif |
| 799 | sdhci_remove_host(host, 1); | 801 | sdhci_remove_host(host, 1); |
| 800 | 802 | ||
| @@ -802,14 +804,14 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) | |||
| 802 | pm_runtime_disable(&pdev->dev); | 804 | pm_runtime_disable(&pdev->dev); |
| 803 | 805 | ||
| 804 | #ifndef CONFIG_PM_RUNTIME | 806 | #ifndef CONFIG_PM_RUNTIME |
| 805 | clk_disable(sc->clk_bus[sc->cur_clk]); | 807 | clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); |
| 806 | #endif | 808 | #endif |
| 807 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { | 809 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 808 | if (sc->clk_bus[ptr]) { | 810 | if (sc->clk_bus[ptr]) { |
| 809 | clk_put(sc->clk_bus[ptr]); | 811 | clk_put(sc->clk_bus[ptr]); |
| 810 | } | 812 | } |
| 811 | } | 813 | } |
| 812 | clk_disable(sc->clk_io); | 814 | clk_disable_unprepare(sc->clk_io); |
| 813 | clk_put(sc->clk_io); | 815 | clk_put(sc->clk_io); |
| 814 | 816 | ||
| 815 | if (pdev->dev.of_node) { | 817 | if (pdev->dev.of_node) { |
| @@ -849,8 +851,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev) | |||
| 849 | 851 | ||
| 850 | ret = sdhci_runtime_suspend_host(host); | 852 | ret = sdhci_runtime_suspend_host(host); |
| 851 | 853 | ||
| 852 | clk_disable(ourhost->clk_bus[ourhost->cur_clk]); | 854 | clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); |
| 853 | clk_disable(busclk); | 855 | clk_disable_unprepare(busclk); |
| 854 | return ret; | 856 | return ret; |
| 855 | } | 857 | } |
| 856 | 858 | ||
| @@ -861,8 +863,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev) | |||
| 861 | struct clk *busclk = ourhost->clk_io; | 863 | struct clk *busclk = ourhost->clk_io; |
| 862 | int ret; | 864 | int ret; |
| 863 | 865 | ||
| 864 | clk_enable(busclk); | 866 | clk_prepare_enable(busclk); |
| 865 | clk_enable(ourhost->clk_bus[ourhost->cur_clk]); | 867 | clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); |
| 866 | ret = sdhci_runtime_resume_host(host); | 868 | ret = sdhci_runtime_resume_host(host); |
| 867 | return ret; | 869 | return ret; |
| 868 | } | 870 | } |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 7922adb42386..c7851c0aabce 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
| @@ -1315,16 +1315,19 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 1315 | */ | 1315 | */ |
| 1316 | if ((host->flags & SDHCI_NEEDS_RETUNING) && | 1316 | if ((host->flags & SDHCI_NEEDS_RETUNING) && |
| 1317 | !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { | 1317 | !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { |
| 1318 | /* eMMC uses cmd21 while sd and sdio use cmd19 */ | 1318 | if (mmc->card) { |
| 1319 | tuning_opcode = mmc->card->type == MMC_TYPE_MMC ? | 1319 | /* eMMC uses cmd21 but sd and sdio use cmd19 */ |
| 1320 | MMC_SEND_TUNING_BLOCK_HS200 : | 1320 | tuning_opcode = |
| 1321 | MMC_SEND_TUNING_BLOCK; | 1321 | mmc->card->type == MMC_TYPE_MMC ? |
| 1322 | spin_unlock_irqrestore(&host->lock, flags); | 1322 | MMC_SEND_TUNING_BLOCK_HS200 : |
| 1323 | sdhci_execute_tuning(mmc, tuning_opcode); | 1323 | MMC_SEND_TUNING_BLOCK; |
| 1324 | spin_lock_irqsave(&host->lock, flags); | 1324 | spin_unlock_irqrestore(&host->lock, flags); |
| 1325 | 1325 | sdhci_execute_tuning(mmc, tuning_opcode); | |
| 1326 | /* Restore original mmc_request structure */ | 1326 | spin_lock_irqsave(&host->lock, flags); |
| 1327 | host->mrq = mrq; | 1327 | |
| 1328 | /* Restore original mmc_request structure */ | ||
| 1329 | host->mrq = mrq; | ||
| 1330 | } | ||
| 1328 | } | 1331 | } |
| 1329 | 1332 | ||
| 1330 | if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) | 1333 | if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) |
| @@ -2837,6 +2840,9 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 2837 | if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) | 2840 | if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) |
| 2838 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 2841 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
| 2839 | 2842 | ||
| 2843 | if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23) | ||
| 2844 | mmc->caps &= ~MMC_CAP_CMD23; | ||
| 2845 | |||
| 2840 | if (caps[0] & SDHCI_CAN_DO_HISPD) | 2846 | if (caps[0] & SDHCI_CAN_DO_HISPD) |
| 2841 | mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; | 2847 | mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; |
| 2842 | 2848 | ||
| @@ -2846,9 +2852,12 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 2846 | 2852 | ||
| 2847 | /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ | 2853 | /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ |
| 2848 | host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc"); | 2854 | host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc"); |
| 2849 | if (IS_ERR(host->vqmmc)) { | 2855 | if (IS_ERR_OR_NULL(host->vqmmc)) { |
| 2850 | pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc)); | 2856 | if (PTR_ERR(host->vqmmc) < 0) { |
| 2851 | host->vqmmc = NULL; | 2857 | pr_info("%s: no vqmmc regulator found\n", |
| 2858 | mmc_hostname(mmc)); | ||
| 2859 | host->vqmmc = NULL; | ||
| 2860 | } | ||
| 2852 | } | 2861 | } |
| 2853 | else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000)) | 2862 | else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000)) |
| 2854 | regulator_enable(host->vqmmc); | 2863 | regulator_enable(host->vqmmc); |
| @@ -2904,9 +2913,12 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 2904 | ocr_avail = 0; | 2913 | ocr_avail = 0; |
| 2905 | 2914 | ||
| 2906 | host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); | 2915 | host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); |
| 2907 | if (IS_ERR(host->vmmc)) { | 2916 | if (IS_ERR_OR_NULL(host->vmmc)) { |
| 2908 | pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); | 2917 | if (PTR_ERR(host->vmmc) < 0) { |
| 2909 | host->vmmc = NULL; | 2918 | pr_info("%s: no vmmc regulator found\n", |
| 2919 | mmc_hostname(mmc)); | ||
| 2920 | host->vmmc = NULL; | ||
| 2921 | } | ||
| 2910 | } else | 2922 | } else |
| 2911 | regulator_enable(host->vmmc); | 2923 | regulator_enable(host->vmmc); |
| 2912 | 2924 | ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 97653ea8942b..71a4a7ed46c5 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
| @@ -278,6 +278,7 @@ struct sdhci_ops { | |||
| 278 | void (*hw_reset)(struct sdhci_host *host); | 278 | void (*hw_reset)(struct sdhci_host *host); |
| 279 | void (*platform_suspend)(struct sdhci_host *host); | 279 | void (*platform_suspend)(struct sdhci_host *host); |
| 280 | void (*platform_resume)(struct sdhci_host *host); | 280 | void (*platform_resume)(struct sdhci_host *host); |
| 281 | void (*platform_init)(struct sdhci_host *host); | ||
| 281 | }; | 282 | }; |
| 282 | 283 | ||
| 283 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS | 284 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS |
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 11d2bc3b51d5..d25bc97dc5c6 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c | |||
| @@ -1466,9 +1466,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) | |||
| 1466 | 1466 | ||
| 1467 | platform_set_drvdata(pdev, NULL); | 1467 | platform_set_drvdata(pdev, NULL); |
| 1468 | 1468 | ||
| 1469 | clk_disable(host->hclk); | ||
| 1469 | mmc_free_host(host->mmc); | 1470 | mmc_free_host(host->mmc); |
| 1470 | pm_runtime_put_sync(&pdev->dev); | 1471 | pm_runtime_put_sync(&pdev->dev); |
| 1471 | clk_disable(host->hclk); | ||
| 1472 | pm_runtime_disable(&pdev->dev); | 1472 | pm_runtime_disable(&pdev->dev); |
| 1473 | 1473 | ||
| 1474 | return 0; | 1474 | return 0; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index c65295dded39..6e5bdd1a31d9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
| @@ -1702,7 +1702,7 @@ static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata) | |||
| 1702 | SHMEM_EEE_ADV_STATUS_SHIFT); | 1702 | SHMEM_EEE_ADV_STATUS_SHIFT); |
| 1703 | if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) { | 1703 | if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) { |
| 1704 | DP(BNX2X_MSG_ETHTOOL, | 1704 | DP(BNX2X_MSG_ETHTOOL, |
| 1705 | "Direct manipulation of EEE advertisment is not supported\n"); | 1705 | "Direct manipulation of EEE advertisement is not supported\n"); |
| 1706 | return -EINVAL; | 1706 | return -EINVAL; |
| 1707 | } | 1707 | } |
| 1708 | 1708 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 6dd0dd076cc5..f6cfdc6cf20f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
| @@ -9941,7 +9941,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
| 9941 | else | 9941 | else |
| 9942 | rc = bnx2x_8483x_disable_eee(phy, params, vars); | 9942 | rc = bnx2x_8483x_disable_eee(phy, params, vars); |
| 9943 | if (rc) { | 9943 | if (rc) { |
| 9944 | DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n"); | 9944 | DP(NETIF_MSG_LINK, "Failed to set EEE advertisement\n"); |
| 9945 | return rc; | 9945 | return rc; |
| 9946 | } | 9946 | } |
| 9947 | } else { | 9947 | } else { |
| @@ -12987,7 +12987,7 @@ static u8 bnx2x_analyze_link_error(struct link_params *params, | |||
| 12987 | DP(NETIF_MSG_LINK, "Analyze TX Fault\n"); | 12987 | DP(NETIF_MSG_LINK, "Analyze TX Fault\n"); |
| 12988 | break; | 12988 | break; |
| 12989 | default: | 12989 | default: |
| 12990 | DP(NETIF_MSG_LINK, "Analyze UNKOWN\n"); | 12990 | DP(NETIF_MSG_LINK, "Analyze UNKNOWN\n"); |
| 12991 | } | 12991 | } |
| 12992 | DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up, | 12992 | DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up, |
| 12993 | old_status, status); | 12993 | old_status, status); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 32eec15fe4c2..730ae2cfa49e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
| @@ -2519,6 +2519,7 @@ int t4_fw_bye(struct adapter *adap, unsigned int mbox) | |||
| 2519 | { | 2519 | { |
| 2520 | struct fw_bye_cmd c; | 2520 | struct fw_bye_cmd c; |
| 2521 | 2521 | ||
| 2522 | memset(&c, 0, sizeof(c)); | ||
| 2522 | INIT_CMD(c, BYE, WRITE); | 2523 | INIT_CMD(c, BYE, WRITE); |
| 2523 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | 2524 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); |
| 2524 | } | 2525 | } |
| @@ -2535,6 +2536,7 @@ int t4_early_init(struct adapter *adap, unsigned int mbox) | |||
| 2535 | { | 2536 | { |
| 2536 | struct fw_initialize_cmd c; | 2537 | struct fw_initialize_cmd c; |
| 2537 | 2538 | ||
| 2539 | memset(&c, 0, sizeof(c)); | ||
| 2538 | INIT_CMD(c, INITIALIZE, WRITE); | 2540 | INIT_CMD(c, INITIALIZE, WRITE); |
| 2539 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | 2541 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); |
| 2540 | } | 2542 | } |
| @@ -2551,6 +2553,7 @@ int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset) | |||
| 2551 | { | 2553 | { |
| 2552 | struct fw_reset_cmd c; | 2554 | struct fw_reset_cmd c; |
| 2553 | 2555 | ||
| 2556 | memset(&c, 0, sizeof(c)); | ||
| 2554 | INIT_CMD(c, RESET, WRITE); | 2557 | INIT_CMD(c, RESET, WRITE); |
| 2555 | c.val = htonl(reset); | 2558 | c.val = htonl(reset); |
| 2556 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); | 2559 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); |
| @@ -2828,7 +2831,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, | |||
| 2828 | HOSTPAGESIZEPF7(sge_hps)); | 2831 | HOSTPAGESIZEPF7(sge_hps)); |
| 2829 | 2832 | ||
| 2830 | t4_set_reg_field(adap, SGE_CONTROL, | 2833 | t4_set_reg_field(adap, SGE_CONTROL, |
| 2831 | INGPADBOUNDARY(INGPADBOUNDARY_MASK) | | 2834 | INGPADBOUNDARY_MASK | |
| 2832 | EGRSTATUSPAGESIZE_MASK, | 2835 | EGRSTATUSPAGESIZE_MASK, |
| 2833 | INGPADBOUNDARY(fl_align_log - 5) | | 2836 | INGPADBOUNDARY(fl_align_log - 5) | |
| 2834 | EGRSTATUSPAGESIZE(stat_len != 64)); | 2837 | EGRSTATUSPAGESIZE(stat_len != 64)); |
| @@ -3278,6 +3281,7 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, | |||
| 3278 | { | 3281 | { |
| 3279 | struct fw_vi_enable_cmd c; | 3282 | struct fw_vi_enable_cmd c; |
| 3280 | 3283 | ||
| 3284 | memset(&c, 0, sizeof(c)); | ||
| 3281 | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | | 3285 | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | |
| 3282 | FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); | 3286 | FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); |
| 3283 | c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); | 3287 | c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); |
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 1d03dcdd5e56..19ac096cb07b 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
| @@ -1353,8 +1353,11 @@ static int gfar_restore(struct device *dev) | |||
| 1353 | struct gfar_private *priv = dev_get_drvdata(dev); | 1353 | struct gfar_private *priv = dev_get_drvdata(dev); |
| 1354 | struct net_device *ndev = priv->ndev; | 1354 | struct net_device *ndev = priv->ndev; |
| 1355 | 1355 | ||
| 1356 | if (!netif_running(ndev)) | 1356 | if (!netif_running(ndev)) { |
| 1357 | netif_device_attach(ndev); | ||
| 1358 | |||
| 1357 | return 0; | 1359 | return 0; |
| 1360 | } | ||
| 1358 | 1361 | ||
| 1359 | gfar_init_bds(ndev); | 1362 | gfar_init_bds(ndev); |
| 1360 | init_registers(ndev); | 1363 | init_registers(ndev); |
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index f8064df10cc4..92317e9c0f73 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c | |||
| @@ -1948,10 +1948,10 @@ jme_close(struct net_device *netdev) | |||
| 1948 | 1948 | ||
| 1949 | JME_NAPI_DISABLE(jme); | 1949 | JME_NAPI_DISABLE(jme); |
| 1950 | 1950 | ||
| 1951 | tasklet_disable(&jme->linkch_task); | 1951 | tasklet_kill(&jme->linkch_task); |
| 1952 | tasklet_disable(&jme->txclean_task); | 1952 | tasklet_kill(&jme->txclean_task); |
| 1953 | tasklet_disable(&jme->rxclean_task); | 1953 | tasklet_kill(&jme->rxclean_task); |
| 1954 | tasklet_disable(&jme->rxempty_task); | 1954 | tasklet_kill(&jme->rxempty_task); |
| 1955 | 1955 | ||
| 1956 | jme_disable_rx_engine(jme); | 1956 | jme_disable_rx_engine(jme); |
| 1957 | jme_disable_tx_engine(jme); | 1957 | jme_disable_tx_engine(jme); |
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index 9b9c2ac5c4c2..d19a143aa5a8 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c | |||
| @@ -4026,7 +4026,7 @@ static void __devexit skge_remove(struct pci_dev *pdev) | |||
| 4026 | dev0 = hw->dev[0]; | 4026 | dev0 = hw->dev[0]; |
| 4027 | unregister_netdev(dev0); | 4027 | unregister_netdev(dev0); |
| 4028 | 4028 | ||
| 4029 | tasklet_disable(&hw->phy_task); | 4029 | tasklet_kill(&hw->phy_task); |
| 4030 | 4030 | ||
| 4031 | spin_lock_irq(&hw->hw_lock); | 4031 | spin_lock_irq(&hw->hw_lock); |
| 4032 | hw->intr_mask = 0; | 4032 | hw->intr_mask = 0; |
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 318fee91c79d..e558edd1cb6c 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c | |||
| @@ -5407,8 +5407,8 @@ static int netdev_close(struct net_device *dev) | |||
| 5407 | /* Delay for receive task to stop scheduling itself. */ | 5407 | /* Delay for receive task to stop scheduling itself. */ |
| 5408 | msleep(2000 / HZ); | 5408 | msleep(2000 / HZ); |
| 5409 | 5409 | ||
| 5410 | tasklet_disable(&hw_priv->rx_tasklet); | 5410 | tasklet_kill(&hw_priv->rx_tasklet); |
| 5411 | tasklet_disable(&hw_priv->tx_tasklet); | 5411 | tasklet_kill(&hw_priv->tx_tasklet); |
| 5412 | free_irq(dev->irq, hw_priv->dev); | 5412 | free_irq(dev->irq, hw_priv->dev); |
| 5413 | 5413 | ||
| 5414 | transmit_cleanup(hw_priv, 0); | 5414 | transmit_cleanup(hw_priv, 0); |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index e7ff886e8047..927aa33d4349 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
| @@ -3827,6 +3827,8 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) | |||
| 3827 | void __iomem *ioaddr = tp->mmio_addr; | 3827 | void __iomem *ioaddr = tp->mmio_addr; |
| 3828 | 3828 | ||
| 3829 | switch (tp->mac_version) { | 3829 | switch (tp->mac_version) { |
| 3830 | case RTL_GIGA_MAC_VER_25: | ||
| 3831 | case RTL_GIGA_MAC_VER_26: | ||
| 3830 | case RTL_GIGA_MAC_VER_29: | 3832 | case RTL_GIGA_MAC_VER_29: |
| 3831 | case RTL_GIGA_MAC_VER_30: | 3833 | case RTL_GIGA_MAC_VER_30: |
| 3832 | case RTL_GIGA_MAC_VER_32: | 3834 | case RTL_GIGA_MAC_VER_32: |
| @@ -4519,6 +4521,9 @@ static void rtl_set_rx_mode(struct net_device *dev) | |||
| 4519 | mc_filter[1] = swab32(data); | 4521 | mc_filter[1] = swab32(data); |
| 4520 | } | 4522 | } |
| 4521 | 4523 | ||
| 4524 | if (tp->mac_version == RTL_GIGA_MAC_VER_35) | ||
| 4525 | mc_filter[1] = mc_filter[0] = 0xffffffff; | ||
| 4526 | |||
| 4522 | RTL_W32(MAR0 + 4, mc_filter[1]); | 4527 | RTL_W32(MAR0 + 4, mc_filter[1]); |
| 4523 | RTL_W32(MAR0 + 0, mc_filter[0]); | 4528 | RTL_W32(MAR0 + 0, mc_filter[0]); |
| 4524 | 4529 | ||
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 0793299bd39e..1d04754a6637 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c | |||
| @@ -990,7 +990,7 @@ static int axienet_stop(struct net_device *ndev) | |||
| 990 | axienet_setoptions(ndev, lp->options & | 990 | axienet_setoptions(ndev, lp->options & |
| 991 | ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); | 991 | ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); |
| 992 | 992 | ||
| 993 | tasklet_disable(&lp->dma_err_tasklet); | 993 | tasklet_kill(&lp->dma_err_tasklet); |
| 994 | 994 | ||
| 995 | free_irq(lp->tx_irq, ndev); | 995 | free_irq(lp->tx_irq, ndev); |
| 996 | free_irq(lp->rx_irq, ndev); | 996 | free_irq(lp->rx_irq, ndev); |
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index c81e278629ff..08d55b6bf272 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/usb/cdc.h> | 31 | #include <linux/usb/cdc.h> |
| 32 | #include <linux/usb/usbnet.h> | 32 | #include <linux/usb/usbnet.h> |
| 33 | #include <linux/gfp.h> | 33 | #include <linux/gfp.h> |
| 34 | #include <linux/if_vlan.h> | ||
| 34 | 35 | ||
| 35 | 36 | ||
| 36 | /* | 37 | /* |
| @@ -92,7 +93,7 @@ static int eem_bind(struct usbnet *dev, struct usb_interface *intf) | |||
| 92 | 93 | ||
| 93 | /* no jumbogram (16K) support for now */ | 94 | /* no jumbogram (16K) support for now */ |
| 94 | 95 | ||
| 95 | dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN; | 96 | dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN + VLAN_HLEN; |
| 96 | dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; | 97 | dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; |
| 97 | 98 | ||
| 98 | return 0; | 99 | return 0; |
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 7479a5761d0d..3286166415b4 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
| @@ -1344,6 +1344,7 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, | |||
| 1344 | } else { | 1344 | } else { |
| 1345 | u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); | 1345 | u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); |
| 1346 | skb_push(skb, 4); | 1346 | skb_push(skb, 4); |
| 1347 | cpu_to_le32s(&csum_preamble); | ||
| 1347 | memcpy(skb->data, &csum_preamble, 4); | 1348 | memcpy(skb->data, &csum_preamble, 4); |
| 1348 | } | 1349 | } |
| 1349 | } | 1350 | } |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index cb04f900cc46..edb81ed06950 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
| @@ -359,10 +359,12 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, | |||
| 359 | void usbnet_defer_kevent (struct usbnet *dev, int work) | 359 | void usbnet_defer_kevent (struct usbnet *dev, int work) |
| 360 | { | 360 | { |
| 361 | set_bit (work, &dev->flags); | 361 | set_bit (work, &dev->flags); |
| 362 | if (!schedule_work (&dev->kevent)) | 362 | if (!schedule_work (&dev->kevent)) { |
| 363 | netdev_err(dev->net, "kevent %d may have been dropped\n", work); | 363 | if (net_ratelimit()) |
| 364 | else | 364 | netdev_err(dev->net, "kevent %d may have been dropped\n", work); |
| 365 | } else { | ||
| 365 | netdev_dbg(dev->net, "kevent %d scheduled\n", work); | 366 | netdev_dbg(dev->net, "kevent %d scheduled\n", work); |
| 367 | } | ||
| 366 | } | 368 | } |
| 367 | EXPORT_SYMBOL_GPL(usbnet_defer_kevent); | 369 | EXPORT_SYMBOL_GPL(usbnet_defer_kevent); |
| 368 | 370 | ||
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c index 192251adf986..282eedec675e 100644 --- a/drivers/net/wireless/b43legacy/pio.c +++ b/drivers/net/wireless/b43legacy/pio.c | |||
| @@ -382,7 +382,7 @@ static void cancel_transfers(struct b43legacy_pioqueue *queue) | |||
| 382 | { | 382 | { |
| 383 | struct b43legacy_pio_txpacket *packet, *tmp_packet; | 383 | struct b43legacy_pio_txpacket *packet, *tmp_packet; |
| 384 | 384 | ||
| 385 | tasklet_disable(&queue->txtask); | 385 | tasklet_kill(&queue->txtask); |
| 386 | 386 | ||
| 387 | list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) | 387 | list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) |
| 388 | free_txpacket(packet, 0); | 388 | free_txpacket(packet, 0); |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 6241fd05bd41..a543746fb354 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
| @@ -320,10 +320,7 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), | |||
| 320 | } else | 320 | } else |
| 321 | next = dev->bus_list.next; | 321 | next = dev->bus_list.next; |
| 322 | 322 | ||
| 323 | /* Run device routines with the device locked */ | ||
| 324 | device_lock(&dev->dev); | ||
| 325 | retval = cb(dev, userdata); | 323 | retval = cb(dev, userdata); |
| 326 | device_unlock(&dev->dev); | ||
| 327 | if (retval) | 324 | if (retval) |
| 328 | break; | 325 | break; |
| 329 | } | 326 | } |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 94c6e2aa03d6..6c94fc9489e7 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
| @@ -398,6 +398,8 @@ static void pci_device_shutdown(struct device *dev) | |||
| 398 | struct pci_dev *pci_dev = to_pci_dev(dev); | 398 | struct pci_dev *pci_dev = to_pci_dev(dev); |
| 399 | struct pci_driver *drv = pci_dev->driver; | 399 | struct pci_driver *drv = pci_dev->driver; |
| 400 | 400 | ||
| 401 | pm_runtime_resume(dev); | ||
| 402 | |||
| 401 | if (drv && drv->shutdown) | 403 | if (drv && drv->shutdown) |
| 402 | drv->shutdown(pci_dev); | 404 | drv->shutdown(pci_dev); |
| 403 | pci_msi_shutdown(pci_dev); | 405 | pci_msi_shutdown(pci_dev); |
| @@ -408,16 +410,6 @@ static void pci_device_shutdown(struct device *dev) | |||
| 408 | * continue to do DMA | 410 | * continue to do DMA |
| 409 | */ | 411 | */ |
| 410 | pci_disable_device(pci_dev); | 412 | pci_disable_device(pci_dev); |
| 411 | |||
| 412 | /* | ||
| 413 | * Devices may be enabled to wake up by runtime PM, but they need not | ||
| 414 | * be supposed to wake up the system from its "power off" state (e.g. | ||
| 415 | * ACPI S5). Therefore disable wakeup for all devices that aren't | ||
| 416 | * supposed to wake up the system at this point. The state argument | ||
| 417 | * will be ignored by pci_enable_wake(). | ||
| 418 | */ | ||
| 419 | if (!device_may_wakeup(dev)) | ||
| 420 | pci_enable_wake(pci_dev, PCI_UNKNOWN, false); | ||
| 421 | } | 413 | } |
| 422 | 414 | ||
| 423 | #ifdef CONFIG_PM | 415 | #ifdef CONFIG_PM |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 02d107b15281..f39378d9da15 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
| @@ -458,40 +458,6 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
| 458 | } | 458 | } |
| 459 | struct device_attribute vga_attr = __ATTR_RO(boot_vga); | 459 | struct device_attribute vga_attr = __ATTR_RO(boot_vga); |
| 460 | 460 | ||
| 461 | static void | ||
| 462 | pci_config_pm_runtime_get(struct pci_dev *pdev) | ||
| 463 | { | ||
| 464 | struct device *dev = &pdev->dev; | ||
| 465 | struct device *parent = dev->parent; | ||
| 466 | |||
| 467 | if (parent) | ||
| 468 | pm_runtime_get_sync(parent); | ||
| 469 | pm_runtime_get_noresume(dev); | ||
| 470 | /* | ||
| 471 | * pdev->current_state is set to PCI_D3cold during suspending, | ||
| 472 | * so wait until suspending completes | ||
| 473 | */ | ||
| 474 | pm_runtime_barrier(dev); | ||
| 475 | /* | ||
| 476 | * Only need to resume devices in D3cold, because config | ||
| 477 | * registers are still accessible for devices suspended but | ||
| 478 | * not in D3cold. | ||
| 479 | */ | ||
| 480 | if (pdev->current_state == PCI_D3cold) | ||
| 481 | pm_runtime_resume(dev); | ||
| 482 | } | ||
| 483 | |||
| 484 | static void | ||
| 485 | pci_config_pm_runtime_put(struct pci_dev *pdev) | ||
| 486 | { | ||
| 487 | struct device *dev = &pdev->dev; | ||
| 488 | struct device *parent = dev->parent; | ||
| 489 | |||
| 490 | pm_runtime_put(dev); | ||
| 491 | if (parent) | ||
| 492 | pm_runtime_put_sync(parent); | ||
| 493 | } | ||
| 494 | |||
| 495 | static ssize_t | 461 | static ssize_t |
| 496 | pci_read_config(struct file *filp, struct kobject *kobj, | 462 | pci_read_config(struct file *filp, struct kobject *kobj, |
| 497 | struct bin_attribute *bin_attr, | 463 | struct bin_attribute *bin_attr, |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 54858838f098..aabf64798bda 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1858,6 +1858,38 @@ bool pci_dev_run_wake(struct pci_dev *dev) | |||
| 1858 | } | 1858 | } |
| 1859 | EXPORT_SYMBOL_GPL(pci_dev_run_wake); | 1859 | EXPORT_SYMBOL_GPL(pci_dev_run_wake); |
| 1860 | 1860 | ||
| 1861 | void pci_config_pm_runtime_get(struct pci_dev *pdev) | ||
| 1862 | { | ||
| 1863 | struct device *dev = &pdev->dev; | ||
| 1864 | struct device *parent = dev->parent; | ||
| 1865 | |||
| 1866 | if (parent) | ||
| 1867 | pm_runtime_get_sync(parent); | ||
| 1868 | pm_runtime_get_noresume(dev); | ||
| 1869 | /* | ||
| 1870 | * pdev->current_state is set to PCI_D3cold during suspending, | ||
| 1871 | * so wait until suspending completes | ||
| 1872 | */ | ||
| 1873 | pm_runtime_barrier(dev); | ||
| 1874 | /* | ||
| 1875 | * Only need to resume devices in D3cold, because config | ||
| 1876 | * registers are still accessible for devices suspended but | ||
| 1877 | * not in D3cold. | ||
| 1878 | */ | ||
| 1879 | if (pdev->current_state == PCI_D3cold) | ||
| 1880 | pm_runtime_resume(dev); | ||
| 1881 | } | ||
| 1882 | |||
| 1883 | void pci_config_pm_runtime_put(struct pci_dev *pdev) | ||
| 1884 | { | ||
| 1885 | struct device *dev = &pdev->dev; | ||
| 1886 | struct device *parent = dev->parent; | ||
| 1887 | |||
| 1888 | pm_runtime_put(dev); | ||
| 1889 | if (parent) | ||
| 1890 | pm_runtime_put_sync(parent); | ||
| 1891 | } | ||
| 1892 | |||
| 1861 | /** | 1893 | /** |
| 1862 | * pci_pm_init - Initialize PM functions of given PCI device | 1894 | * pci_pm_init - Initialize PM functions of given PCI device |
| 1863 | * @dev: PCI device to handle. | 1895 | * @dev: PCI device to handle. |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index bacbcba69cf3..fd92aab9904b 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -72,6 +72,8 @@ extern void pci_disable_enabled_device(struct pci_dev *dev); | |||
| 72 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); | 72 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); |
| 73 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | 73 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); |
| 74 | extern void pci_wakeup_bus(struct pci_bus *bus); | 74 | extern void pci_wakeup_bus(struct pci_bus *bus); |
| 75 | extern void pci_config_pm_runtime_get(struct pci_dev *dev); | ||
| 76 | extern void pci_config_pm_runtime_put(struct pci_dev *dev); | ||
| 75 | extern void pci_pm_init(struct pci_dev *dev); | 77 | extern void pci_pm_init(struct pci_dev *dev); |
| 76 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | 78 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
| 77 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 79 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 06bad96af415..af4e31cd3a3b 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
| @@ -213,6 +213,7 @@ static int report_error_detected(struct pci_dev *dev, void *data) | |||
| 213 | struct aer_broadcast_data *result_data; | 213 | struct aer_broadcast_data *result_data; |
| 214 | result_data = (struct aer_broadcast_data *) data; | 214 | result_data = (struct aer_broadcast_data *) data; |
| 215 | 215 | ||
| 216 | device_lock(&dev->dev); | ||
| 216 | dev->error_state = result_data->state; | 217 | dev->error_state = result_data->state; |
| 217 | 218 | ||
| 218 | if (!dev->driver || | 219 | if (!dev->driver || |
| @@ -231,12 +232,14 @@ static int report_error_detected(struct pci_dev *dev, void *data) | |||
| 231 | dev->driver ? | 232 | dev->driver ? |
| 232 | "no AER-aware driver" : "no driver"); | 233 | "no AER-aware driver" : "no driver"); |
| 233 | } | 234 | } |
| 234 | return 0; | 235 | goto out; |
| 235 | } | 236 | } |
| 236 | 237 | ||
| 237 | err_handler = dev->driver->err_handler; | 238 | err_handler = dev->driver->err_handler; |
| 238 | vote = err_handler->error_detected(dev, result_data->state); | 239 | vote = err_handler->error_detected(dev, result_data->state); |
| 239 | result_data->result = merge_result(result_data->result, vote); | 240 | result_data->result = merge_result(result_data->result, vote); |
| 241 | out: | ||
| 242 | device_unlock(&dev->dev); | ||
| 240 | return 0; | 243 | return 0; |
| 241 | } | 244 | } |
| 242 | 245 | ||
| @@ -247,14 +250,17 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data) | |||
| 247 | struct aer_broadcast_data *result_data; | 250 | struct aer_broadcast_data *result_data; |
| 248 | result_data = (struct aer_broadcast_data *) data; | 251 | result_data = (struct aer_broadcast_data *) data; |
| 249 | 252 | ||
| 253 | device_lock(&dev->dev); | ||
| 250 | if (!dev->driver || | 254 | if (!dev->driver || |
| 251 | !dev->driver->err_handler || | 255 | !dev->driver->err_handler || |
| 252 | !dev->driver->err_handler->mmio_enabled) | 256 | !dev->driver->err_handler->mmio_enabled) |
| 253 | return 0; | 257 | goto out; |
| 254 | 258 | ||
| 255 | err_handler = dev->driver->err_handler; | 259 | err_handler = dev->driver->err_handler; |
| 256 | vote = err_handler->mmio_enabled(dev); | 260 | vote = err_handler->mmio_enabled(dev); |
| 257 | result_data->result = merge_result(result_data->result, vote); | 261 | result_data->result = merge_result(result_data->result, vote); |
| 262 | out: | ||
| 263 | device_unlock(&dev->dev); | ||
| 258 | return 0; | 264 | return 0; |
| 259 | } | 265 | } |
| 260 | 266 | ||
| @@ -265,14 +271,17 @@ static int report_slot_reset(struct pci_dev *dev, void *data) | |||
| 265 | struct aer_broadcast_data *result_data; | 271 | struct aer_broadcast_data *result_data; |
| 266 | result_data = (struct aer_broadcast_data *) data; | 272 | result_data = (struct aer_broadcast_data *) data; |
| 267 | 273 | ||
| 274 | device_lock(&dev->dev); | ||
| 268 | if (!dev->driver || | 275 | if (!dev->driver || |
| 269 | !dev->driver->err_handler || | 276 | !dev->driver->err_handler || |
| 270 | !dev->driver->err_handler->slot_reset) | 277 | !dev->driver->err_handler->slot_reset) |
| 271 | return 0; | 278 | goto out; |
| 272 | 279 | ||
| 273 | err_handler = dev->driver->err_handler; | 280 | err_handler = dev->driver->err_handler; |
| 274 | vote = err_handler->slot_reset(dev); | 281 | vote = err_handler->slot_reset(dev); |
| 275 | result_data->result = merge_result(result_data->result, vote); | 282 | result_data->result = merge_result(result_data->result, vote); |
| 283 | out: | ||
| 284 | device_unlock(&dev->dev); | ||
| 276 | return 0; | 285 | return 0; |
| 277 | } | 286 | } |
| 278 | 287 | ||
| @@ -280,15 +289,18 @@ static int report_resume(struct pci_dev *dev, void *data) | |||
| 280 | { | 289 | { |
| 281 | const struct pci_error_handlers *err_handler; | 290 | const struct pci_error_handlers *err_handler; |
| 282 | 291 | ||
| 292 | device_lock(&dev->dev); | ||
| 283 | dev->error_state = pci_channel_io_normal; | 293 | dev->error_state = pci_channel_io_normal; |
| 284 | 294 | ||
| 285 | if (!dev->driver || | 295 | if (!dev->driver || |
| 286 | !dev->driver->err_handler || | 296 | !dev->driver->err_handler || |
| 287 | !dev->driver->err_handler->resume) | 297 | !dev->driver->err_handler->resume) |
| 288 | return 0; | 298 | goto out; |
| 289 | 299 | ||
| 290 | err_handler = dev->driver->err_handler; | 300 | err_handler = dev->driver->err_handler; |
| 291 | err_handler->resume(dev); | 301 | err_handler->resume(dev); |
| 302 | out: | ||
| 303 | device_unlock(&dev->dev); | ||
| 292 | return 0; | 304 | return 0; |
| 293 | } | 305 | } |
| 294 | 306 | ||
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index d03a7a39b2d8..ed129b414624 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
| @@ -272,7 +272,8 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | /* Hot-Plug Capable */ | 274 | /* Hot-Plug Capable */ |
| 275 | if (cap_mask & PCIE_PORT_SERVICE_HP) { | 275 | if ((cap_mask & PCIE_PORT_SERVICE_HP) && |
| 276 | dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT) { | ||
| 276 | pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); | 277 | pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); |
| 277 | if (reg32 & PCI_EXP_SLTCAP_HPC) { | 278 | if (reg32 & PCI_EXP_SLTCAP_HPC) { |
| 278 | services |= PCIE_PORT_SERVICE_HP; | 279 | services |= PCIE_PORT_SERVICE_HP; |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index eb907a8faf2a..9b8505ccc56d 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
| @@ -76,6 +76,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp | |||
| 76 | if (!access_ok(VERIFY_WRITE, buf, cnt)) | 76 | if (!access_ok(VERIFY_WRITE, buf, cnt)) |
| 77 | return -EINVAL; | 77 | return -EINVAL; |
| 78 | 78 | ||
| 79 | pci_config_pm_runtime_get(dev); | ||
| 80 | |||
| 79 | if ((pos & 1) && cnt) { | 81 | if ((pos & 1) && cnt) { |
| 80 | unsigned char val; | 82 | unsigned char val; |
| 81 | pci_user_read_config_byte(dev, pos, &val); | 83 | pci_user_read_config_byte(dev, pos, &val); |
| @@ -121,6 +123,8 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp | |||
| 121 | cnt--; | 123 | cnt--; |
| 122 | } | 124 | } |
| 123 | 125 | ||
| 126 | pci_config_pm_runtime_put(dev); | ||
| 127 | |||
| 124 | *ppos = pos; | 128 | *ppos = pos; |
| 125 | return nbytes; | 129 | return nbytes; |
| 126 | } | 130 | } |
| @@ -146,6 +150,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof | |||
| 146 | if (!access_ok(VERIFY_READ, buf, cnt)) | 150 | if (!access_ok(VERIFY_READ, buf, cnt)) |
| 147 | return -EINVAL; | 151 | return -EINVAL; |
| 148 | 152 | ||
| 153 | pci_config_pm_runtime_get(dev); | ||
| 154 | |||
| 149 | if ((pos & 1) && cnt) { | 155 | if ((pos & 1) && cnt) { |
| 150 | unsigned char val; | 156 | unsigned char val; |
| 151 | __get_user(val, buf); | 157 | __get_user(val, buf); |
| @@ -191,6 +197,8 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof | |||
| 191 | cnt--; | 197 | cnt--; |
| 192 | } | 198 | } |
| 193 | 199 | ||
| 200 | pci_config_pm_runtime_put(dev); | ||
| 201 | |||
| 194 | *ppos = pos; | 202 | *ppos = pos; |
| 195 | i_size_write(ino, dp->size); | 203 | i_size_write(ino, dp->size); |
| 196 | return nbytes; | 204 | return nbytes; |
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 7bf914df6e91..d96caefd914a 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
| @@ -179,11 +179,13 @@ config PINCTRL_COH901 | |||
| 179 | 179 | ||
| 180 | config PINCTRL_SAMSUNG | 180 | config PINCTRL_SAMSUNG |
| 181 | bool "Samsung pinctrl driver" | 181 | bool "Samsung pinctrl driver" |
| 182 | depends on OF && GPIOLIB | ||
| 182 | select PINMUX | 183 | select PINMUX |
| 183 | select PINCONF | 184 | select PINCONF |
| 184 | 185 | ||
| 185 | config PINCTRL_EXYNOS4 | 186 | config PINCTRL_EXYNOS4 |
| 186 | bool "Pinctrl driver data for Exynos4 SoC" | 187 | bool "Pinctrl driver data for Exynos4 SoC" |
| 188 | depends on OF && GPIOLIB | ||
| 187 | select PINCTRL_SAMSUNG | 189 | select PINCTRL_SAMSUNG |
| 188 | 190 | ||
| 189 | config PINCTRL_MVEBU | 191 | config PINCTRL_MVEBU |
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index 5d4f44f462f0..b1fd6ee33c6c 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c | |||
| @@ -244,7 +244,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, | |||
| 244 | else | 244 | else |
| 245 | temp = ~muxreg->val; | 245 | temp = ~muxreg->val; |
| 246 | 246 | ||
| 247 | val |= temp; | 247 | val |= muxreg->mask & temp; |
| 248 | pmx_writel(pmx, val, muxreg->reg); | 248 | pmx_writel(pmx, val, muxreg->reg); |
| 249 | } | 249 | } |
| 250 | } | 250 | } |
diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c index d6cca8c81b92..0436fc7895d6 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/drivers/pinctrl/spear/pinctrl-spear1310.c | |||
| @@ -25,8 +25,8 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { | |||
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | /* registers */ | 27 | /* registers */ |
| 28 | #define PERIP_CFG 0x32C | 28 | #define PERIP_CFG 0x3B0 |
| 29 | #define MCIF_SEL_SHIFT 3 | 29 | #define MCIF_SEL_SHIFT 5 |
| 30 | #define MCIF_SEL_SD (0x1 << MCIF_SEL_SHIFT) | 30 | #define MCIF_SEL_SD (0x1 << MCIF_SEL_SHIFT) |
| 31 | #define MCIF_SEL_CF (0x2 << MCIF_SEL_SHIFT) | 31 | #define MCIF_SEL_CF (0x2 << MCIF_SEL_SHIFT) |
| 32 | #define MCIF_SEL_XD (0x3 << MCIF_SEL_SHIFT) | 32 | #define MCIF_SEL_XD (0x3 << MCIF_SEL_SHIFT) |
| @@ -164,6 +164,10 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { | |||
| 164 | #define PMX_SSP0_CS0_MASK (1 << 29) | 164 | #define PMX_SSP0_CS0_MASK (1 << 29) |
| 165 | #define PMX_SSP0_CS1_2_MASK (1 << 30) | 165 | #define PMX_SSP0_CS1_2_MASK (1 << 30) |
| 166 | 166 | ||
| 167 | #define PAD_DIRECTION_SEL_0 0x65C | ||
| 168 | #define PAD_DIRECTION_SEL_1 0x660 | ||
| 169 | #define PAD_DIRECTION_SEL_2 0x664 | ||
| 170 | |||
| 167 | /* combined macros */ | 171 | /* combined macros */ |
| 168 | #define PMX_GMII_MASK (PMX_GMIICLK_MASK | \ | 172 | #define PMX_GMII_MASK (PMX_GMIICLK_MASK | \ |
| 169 | PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \ | 173 | PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \ |
| @@ -237,6 +241,10 @@ static struct spear_muxreg i2c0_muxreg[] = { | |||
| 237 | .reg = PAD_FUNCTION_EN_0, | 241 | .reg = PAD_FUNCTION_EN_0, |
| 238 | .mask = PMX_I2C0_MASK, | 242 | .mask = PMX_I2C0_MASK, |
| 239 | .val = PMX_I2C0_MASK, | 243 | .val = PMX_I2C0_MASK, |
| 244 | }, { | ||
| 245 | .reg = PAD_DIRECTION_SEL_0, | ||
| 246 | .mask = PMX_I2C0_MASK, | ||
| 247 | .val = PMX_I2C0_MASK, | ||
| 240 | }, | 248 | }, |
| 241 | }; | 249 | }; |
| 242 | 250 | ||
| @@ -269,6 +277,10 @@ static struct spear_muxreg ssp0_muxreg[] = { | |||
| 269 | .reg = PAD_FUNCTION_EN_0, | 277 | .reg = PAD_FUNCTION_EN_0, |
| 270 | .mask = PMX_SSP0_MASK, | 278 | .mask = PMX_SSP0_MASK, |
| 271 | .val = PMX_SSP0_MASK, | 279 | .val = PMX_SSP0_MASK, |
| 280 | }, { | ||
| 281 | .reg = PAD_DIRECTION_SEL_0, | ||
| 282 | .mask = PMX_SSP0_MASK, | ||
| 283 | .val = PMX_SSP0_MASK, | ||
| 272 | }, | 284 | }, |
| 273 | }; | 285 | }; |
| 274 | 286 | ||
| @@ -294,6 +306,10 @@ static struct spear_muxreg ssp0_cs0_muxreg[] = { | |||
| 294 | .reg = PAD_FUNCTION_EN_2, | 306 | .reg = PAD_FUNCTION_EN_2, |
| 295 | .mask = PMX_SSP0_CS0_MASK, | 307 | .mask = PMX_SSP0_CS0_MASK, |
| 296 | .val = PMX_SSP0_CS0_MASK, | 308 | .val = PMX_SSP0_CS0_MASK, |
| 309 | }, { | ||
| 310 | .reg = PAD_DIRECTION_SEL_2, | ||
| 311 | .mask = PMX_SSP0_CS0_MASK, | ||
| 312 | .val = PMX_SSP0_CS0_MASK, | ||
| 297 | }, | 313 | }, |
| 298 | }; | 314 | }; |
| 299 | 315 | ||
| @@ -319,6 +335,10 @@ static struct spear_muxreg ssp0_cs1_2_muxreg[] = { | |||
| 319 | .reg = PAD_FUNCTION_EN_2, | 335 | .reg = PAD_FUNCTION_EN_2, |
| 320 | .mask = PMX_SSP0_CS1_2_MASK, | 336 | .mask = PMX_SSP0_CS1_2_MASK, |
| 321 | .val = PMX_SSP0_CS1_2_MASK, | 337 | .val = PMX_SSP0_CS1_2_MASK, |
| 338 | }, { | ||
| 339 | .reg = PAD_DIRECTION_SEL_2, | ||
| 340 | .mask = PMX_SSP0_CS1_2_MASK, | ||
| 341 | .val = PMX_SSP0_CS1_2_MASK, | ||
| 322 | }, | 342 | }, |
| 323 | }; | 343 | }; |
| 324 | 344 | ||
| @@ -352,6 +372,10 @@ static struct spear_muxreg i2s0_muxreg[] = { | |||
| 352 | .reg = PAD_FUNCTION_EN_0, | 372 | .reg = PAD_FUNCTION_EN_0, |
| 353 | .mask = PMX_I2S0_MASK, | 373 | .mask = PMX_I2S0_MASK, |
| 354 | .val = PMX_I2S0_MASK, | 374 | .val = PMX_I2S0_MASK, |
| 375 | }, { | ||
| 376 | .reg = PAD_DIRECTION_SEL_0, | ||
| 377 | .mask = PMX_I2S0_MASK, | ||
| 378 | .val = PMX_I2S0_MASK, | ||
| 355 | }, | 379 | }, |
| 356 | }; | 380 | }; |
| 357 | 381 | ||
| @@ -384,6 +408,10 @@ static struct spear_muxreg i2s1_muxreg[] = { | |||
| 384 | .reg = PAD_FUNCTION_EN_1, | 408 | .reg = PAD_FUNCTION_EN_1, |
| 385 | .mask = PMX_I2S1_MASK, | 409 | .mask = PMX_I2S1_MASK, |
| 386 | .val = PMX_I2S1_MASK, | 410 | .val = PMX_I2S1_MASK, |
| 411 | }, { | ||
| 412 | .reg = PAD_DIRECTION_SEL_1, | ||
| 413 | .mask = PMX_I2S1_MASK, | ||
| 414 | .val = PMX_I2S1_MASK, | ||
| 387 | }, | 415 | }, |
| 388 | }; | 416 | }; |
| 389 | 417 | ||
| @@ -418,6 +446,10 @@ static struct spear_muxreg clcd_muxreg[] = { | |||
| 418 | .reg = PAD_FUNCTION_EN_0, | 446 | .reg = PAD_FUNCTION_EN_0, |
| 419 | .mask = PMX_CLCD1_MASK, | 447 | .mask = PMX_CLCD1_MASK, |
| 420 | .val = PMX_CLCD1_MASK, | 448 | .val = PMX_CLCD1_MASK, |
| 449 | }, { | ||
| 450 | .reg = PAD_DIRECTION_SEL_0, | ||
| 451 | .mask = PMX_CLCD1_MASK, | ||
| 452 | .val = PMX_CLCD1_MASK, | ||
| 421 | }, | 453 | }, |
| 422 | }; | 454 | }; |
| 423 | 455 | ||
| @@ -443,6 +475,10 @@ static struct spear_muxreg clcd_high_res_muxreg[] = { | |||
| 443 | .reg = PAD_FUNCTION_EN_1, | 475 | .reg = PAD_FUNCTION_EN_1, |
| 444 | .mask = PMX_CLCD2_MASK, | 476 | .mask = PMX_CLCD2_MASK, |
| 445 | .val = PMX_CLCD2_MASK, | 477 | .val = PMX_CLCD2_MASK, |
| 478 | }, { | ||
| 479 | .reg = PAD_DIRECTION_SEL_1, | ||
| 480 | .mask = PMX_CLCD2_MASK, | ||
| 481 | .val = PMX_CLCD2_MASK, | ||
| 446 | }, | 482 | }, |
| 447 | }; | 483 | }; |
| 448 | 484 | ||
| @@ -461,7 +497,7 @@ static struct spear_pingroup clcd_high_res_pingroup = { | |||
| 461 | .nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux), | 497 | .nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux), |
| 462 | }; | 498 | }; |
| 463 | 499 | ||
| 464 | static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res" }; | 500 | static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res_grp" }; |
| 465 | static struct spear_function clcd_function = { | 501 | static struct spear_function clcd_function = { |
| 466 | .name = "clcd", | 502 | .name = "clcd", |
| 467 | .groups = clcd_grps, | 503 | .groups = clcd_grps, |
| @@ -479,6 +515,14 @@ static struct spear_muxreg arm_gpio_muxreg[] = { | |||
| 479 | .reg = PAD_FUNCTION_EN_1, | 515 | .reg = PAD_FUNCTION_EN_1, |
| 480 | .mask = PMX_EGPIO_1_GRP_MASK, | 516 | .mask = PMX_EGPIO_1_GRP_MASK, |
| 481 | .val = PMX_EGPIO_1_GRP_MASK, | 517 | .val = PMX_EGPIO_1_GRP_MASK, |
| 518 | }, { | ||
| 519 | .reg = PAD_DIRECTION_SEL_0, | ||
| 520 | .mask = PMX_EGPIO_0_GRP_MASK, | ||
| 521 | .val = PMX_EGPIO_0_GRP_MASK, | ||
| 522 | }, { | ||
| 523 | .reg = PAD_DIRECTION_SEL_1, | ||
| 524 | .mask = PMX_EGPIO_1_GRP_MASK, | ||
| 525 | .val = PMX_EGPIO_1_GRP_MASK, | ||
| 482 | }, | 526 | }, |
| 483 | }; | 527 | }; |
| 484 | 528 | ||
| @@ -511,6 +555,10 @@ static struct spear_muxreg smi_2_chips_muxreg[] = { | |||
| 511 | .reg = PAD_FUNCTION_EN_0, | 555 | .reg = PAD_FUNCTION_EN_0, |
| 512 | .mask = PMX_SMI_MASK, | 556 | .mask = PMX_SMI_MASK, |
| 513 | .val = PMX_SMI_MASK, | 557 | .val = PMX_SMI_MASK, |
| 558 | }, { | ||
| 559 | .reg = PAD_DIRECTION_SEL_0, | ||
| 560 | .mask = PMX_SMI_MASK, | ||
| 561 | .val = PMX_SMI_MASK, | ||
| 514 | }, | 562 | }, |
| 515 | }; | 563 | }; |
| 516 | 564 | ||
| @@ -539,6 +587,14 @@ static struct spear_muxreg smi_4_chips_muxreg[] = { | |||
| 539 | .reg = PAD_FUNCTION_EN_1, | 587 | .reg = PAD_FUNCTION_EN_1, |
| 540 | .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, | 588 | .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, |
| 541 | .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, | 589 | .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, |
| 590 | }, { | ||
| 591 | .reg = PAD_DIRECTION_SEL_0, | ||
| 592 | .mask = PMX_SMI_MASK, | ||
| 593 | .val = PMX_SMI_MASK, | ||
| 594 | }, { | ||
| 595 | .reg = PAD_DIRECTION_SEL_1, | ||
| 596 | .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, | ||
| 597 | .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, | ||
| 542 | }, | 598 | }, |
| 543 | }; | 599 | }; |
| 544 | 600 | ||
| @@ -573,6 +629,10 @@ static struct spear_muxreg gmii_muxreg[] = { | |||
| 573 | .reg = PAD_FUNCTION_EN_0, | 629 | .reg = PAD_FUNCTION_EN_0, |
| 574 | .mask = PMX_GMII_MASK, | 630 | .mask = PMX_GMII_MASK, |
| 575 | .val = PMX_GMII_MASK, | 631 | .val = PMX_GMII_MASK, |
| 632 | }, { | ||
| 633 | .reg = PAD_DIRECTION_SEL_0, | ||
| 634 | .mask = PMX_GMII_MASK, | ||
| 635 | .val = PMX_GMII_MASK, | ||
| 576 | }, | 636 | }, |
| 577 | }; | 637 | }; |
| 578 | 638 | ||
| @@ -615,6 +675,18 @@ static struct spear_muxreg rgmii_muxreg[] = { | |||
| 615 | .reg = PAD_FUNCTION_EN_2, | 675 | .reg = PAD_FUNCTION_EN_2, |
| 616 | .mask = PMX_RGMII_REG2_MASK, | 676 | .mask = PMX_RGMII_REG2_MASK, |
| 617 | .val = 0, | 677 | .val = 0, |
| 678 | }, { | ||
| 679 | .reg = PAD_DIRECTION_SEL_0, | ||
| 680 | .mask = PMX_RGMII_REG0_MASK, | ||
| 681 | .val = PMX_RGMII_REG0_MASK, | ||
| 682 | }, { | ||
| 683 | .reg = PAD_DIRECTION_SEL_1, | ||
| 684 | .mask = PMX_RGMII_REG1_MASK, | ||
| 685 | .val = PMX_RGMII_REG1_MASK, | ||
| 686 | }, { | ||
| 687 | .reg = PAD_DIRECTION_SEL_2, | ||
| 688 | .mask = PMX_RGMII_REG2_MASK, | ||
| 689 | .val = PMX_RGMII_REG2_MASK, | ||
| 618 | }, | 690 | }, |
| 619 | }; | 691 | }; |
| 620 | 692 | ||
| @@ -649,6 +721,10 @@ static struct spear_muxreg smii_0_1_2_muxreg[] = { | |||
| 649 | .reg = PAD_FUNCTION_EN_1, | 721 | .reg = PAD_FUNCTION_EN_1, |
| 650 | .mask = PMX_SMII_0_1_2_MASK, | 722 | .mask = PMX_SMII_0_1_2_MASK, |
| 651 | .val = 0, | 723 | .val = 0, |
| 724 | }, { | ||
| 725 | .reg = PAD_DIRECTION_SEL_1, | ||
| 726 | .mask = PMX_SMII_0_1_2_MASK, | ||
| 727 | .val = PMX_SMII_0_1_2_MASK, | ||
| 652 | }, | 728 | }, |
| 653 | }; | 729 | }; |
| 654 | 730 | ||
| @@ -681,6 +757,10 @@ static struct spear_muxreg ras_mii_txclk_muxreg[] = { | |||
| 681 | .reg = PAD_FUNCTION_EN_1, | 757 | .reg = PAD_FUNCTION_EN_1, |
| 682 | .mask = PMX_NFCE2_MASK, | 758 | .mask = PMX_NFCE2_MASK, |
| 683 | .val = 0, | 759 | .val = 0, |
| 760 | }, { | ||
| 761 | .reg = PAD_DIRECTION_SEL_1, | ||
| 762 | .mask = PMX_NFCE2_MASK, | ||
| 763 | .val = PMX_NFCE2_MASK, | ||
| 684 | }, | 764 | }, |
| 685 | }; | 765 | }; |
| 686 | 766 | ||
| @@ -721,6 +801,14 @@ static struct spear_muxreg nand_8bit_muxreg[] = { | |||
| 721 | .reg = PAD_FUNCTION_EN_1, | 801 | .reg = PAD_FUNCTION_EN_1, |
| 722 | .mask = PMX_NAND8BIT_1_MASK, | 802 | .mask = PMX_NAND8BIT_1_MASK, |
| 723 | .val = PMX_NAND8BIT_1_MASK, | 803 | .val = PMX_NAND8BIT_1_MASK, |
| 804 | }, { | ||
| 805 | .reg = PAD_DIRECTION_SEL_0, | ||
| 806 | .mask = PMX_NAND8BIT_0_MASK, | ||
| 807 | .val = PMX_NAND8BIT_0_MASK, | ||
| 808 | }, { | ||
| 809 | .reg = PAD_DIRECTION_SEL_1, | ||
| 810 | .mask = PMX_NAND8BIT_1_MASK, | ||
| 811 | .val = PMX_NAND8BIT_1_MASK, | ||
| 724 | }, | 812 | }, |
| 725 | }; | 813 | }; |
| 726 | 814 | ||
| @@ -747,6 +835,10 @@ static struct spear_muxreg nand_16bit_muxreg[] = { | |||
| 747 | .reg = PAD_FUNCTION_EN_1, | 835 | .reg = PAD_FUNCTION_EN_1, |
| 748 | .mask = PMX_NAND16BIT_1_MASK, | 836 | .mask = PMX_NAND16BIT_1_MASK, |
| 749 | .val = PMX_NAND16BIT_1_MASK, | 837 | .val = PMX_NAND16BIT_1_MASK, |
| 838 | }, { | ||
| 839 | .reg = PAD_DIRECTION_SEL_1, | ||
| 840 | .mask = PMX_NAND16BIT_1_MASK, | ||
| 841 | .val = PMX_NAND16BIT_1_MASK, | ||
| 750 | }, | 842 | }, |
| 751 | }; | 843 | }; |
| 752 | 844 | ||
| @@ -772,6 +864,10 @@ static struct spear_muxreg nand_4_chips_muxreg[] = { | |||
| 772 | .reg = PAD_FUNCTION_EN_1, | 864 | .reg = PAD_FUNCTION_EN_1, |
| 773 | .mask = PMX_NAND_4CHIPS_MASK, | 865 | .mask = PMX_NAND_4CHIPS_MASK, |
| 774 | .val = PMX_NAND_4CHIPS_MASK, | 866 | .val = PMX_NAND_4CHIPS_MASK, |
| 867 | }, { | ||
| 868 | .reg = PAD_DIRECTION_SEL_1, | ||
| 869 | .mask = PMX_NAND_4CHIPS_MASK, | ||
| 870 | .val = PMX_NAND_4CHIPS_MASK, | ||
| 775 | }, | 871 | }, |
| 776 | }; | 872 | }; |
| 777 | 873 | ||
| @@ -833,6 +929,10 @@ static struct spear_muxreg keyboard_rowcol6_8_muxreg[] = { | |||
| 833 | .reg = PAD_FUNCTION_EN_1, | 929 | .reg = PAD_FUNCTION_EN_1, |
| 834 | .mask = PMX_KBD_ROWCOL68_MASK, | 930 | .mask = PMX_KBD_ROWCOL68_MASK, |
| 835 | .val = PMX_KBD_ROWCOL68_MASK, | 931 | .val = PMX_KBD_ROWCOL68_MASK, |
| 932 | }, { | ||
| 933 | .reg = PAD_DIRECTION_SEL_1, | ||
| 934 | .mask = PMX_KBD_ROWCOL68_MASK, | ||
| 935 | .val = PMX_KBD_ROWCOL68_MASK, | ||
| 836 | }, | 936 | }, |
| 837 | }; | 937 | }; |
| 838 | 938 | ||
| @@ -866,6 +966,10 @@ static struct spear_muxreg uart0_muxreg[] = { | |||
| 866 | .reg = PAD_FUNCTION_EN_0, | 966 | .reg = PAD_FUNCTION_EN_0, |
| 867 | .mask = PMX_UART0_MASK, | 967 | .mask = PMX_UART0_MASK, |
| 868 | .val = PMX_UART0_MASK, | 968 | .val = PMX_UART0_MASK, |
| 969 | }, { | ||
| 970 | .reg = PAD_DIRECTION_SEL_0, | ||
| 971 | .mask = PMX_UART0_MASK, | ||
| 972 | .val = PMX_UART0_MASK, | ||
| 869 | }, | 973 | }, |
| 870 | }; | 974 | }; |
| 871 | 975 | ||
| @@ -891,6 +995,10 @@ static struct spear_muxreg uart0_modem_muxreg[] = { | |||
| 891 | .reg = PAD_FUNCTION_EN_1, | 995 | .reg = PAD_FUNCTION_EN_1, |
| 892 | .mask = PMX_UART0_MODEM_MASK, | 996 | .mask = PMX_UART0_MODEM_MASK, |
| 893 | .val = PMX_UART0_MODEM_MASK, | 997 | .val = PMX_UART0_MODEM_MASK, |
| 998 | }, { | ||
| 999 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1000 | .mask = PMX_UART0_MODEM_MASK, | ||
| 1001 | .val = PMX_UART0_MODEM_MASK, | ||
| 894 | }, | 1002 | }, |
| 895 | }; | 1003 | }; |
| 896 | 1004 | ||
| @@ -923,6 +1031,10 @@ static struct spear_muxreg gpt0_tmr0_muxreg[] = { | |||
| 923 | .reg = PAD_FUNCTION_EN_1, | 1031 | .reg = PAD_FUNCTION_EN_1, |
| 924 | .mask = PMX_GPT0_TMR0_MASK, | 1032 | .mask = PMX_GPT0_TMR0_MASK, |
| 925 | .val = PMX_GPT0_TMR0_MASK, | 1033 | .val = PMX_GPT0_TMR0_MASK, |
| 1034 | }, { | ||
| 1035 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1036 | .mask = PMX_GPT0_TMR0_MASK, | ||
| 1037 | .val = PMX_GPT0_TMR0_MASK, | ||
| 926 | }, | 1038 | }, |
| 927 | }; | 1039 | }; |
| 928 | 1040 | ||
| @@ -948,6 +1060,10 @@ static struct spear_muxreg gpt0_tmr1_muxreg[] = { | |||
| 948 | .reg = PAD_FUNCTION_EN_1, | 1060 | .reg = PAD_FUNCTION_EN_1, |
| 949 | .mask = PMX_GPT0_TMR1_MASK, | 1061 | .mask = PMX_GPT0_TMR1_MASK, |
| 950 | .val = PMX_GPT0_TMR1_MASK, | 1062 | .val = PMX_GPT0_TMR1_MASK, |
| 1063 | }, { | ||
| 1064 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1065 | .mask = PMX_GPT0_TMR1_MASK, | ||
| 1066 | .val = PMX_GPT0_TMR1_MASK, | ||
| 951 | }, | 1067 | }, |
| 952 | }; | 1068 | }; |
| 953 | 1069 | ||
| @@ -980,6 +1096,10 @@ static struct spear_muxreg gpt1_tmr0_muxreg[] = { | |||
| 980 | .reg = PAD_FUNCTION_EN_1, | 1096 | .reg = PAD_FUNCTION_EN_1, |
| 981 | .mask = PMX_GPT1_TMR0_MASK, | 1097 | .mask = PMX_GPT1_TMR0_MASK, |
| 982 | .val = PMX_GPT1_TMR0_MASK, | 1098 | .val = PMX_GPT1_TMR0_MASK, |
| 1099 | }, { | ||
| 1100 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1101 | .mask = PMX_GPT1_TMR0_MASK, | ||
| 1102 | .val = PMX_GPT1_TMR0_MASK, | ||
| 983 | }, | 1103 | }, |
| 984 | }; | 1104 | }; |
| 985 | 1105 | ||
| @@ -1005,6 +1125,10 @@ static struct spear_muxreg gpt1_tmr1_muxreg[] = { | |||
| 1005 | .reg = PAD_FUNCTION_EN_1, | 1125 | .reg = PAD_FUNCTION_EN_1, |
| 1006 | .mask = PMX_GPT1_TMR1_MASK, | 1126 | .mask = PMX_GPT1_TMR1_MASK, |
| 1007 | .val = PMX_GPT1_TMR1_MASK, | 1127 | .val = PMX_GPT1_TMR1_MASK, |
| 1128 | }, { | ||
| 1129 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1130 | .mask = PMX_GPT1_TMR1_MASK, | ||
| 1131 | .val = PMX_GPT1_TMR1_MASK, | ||
| 1008 | }, | 1132 | }, |
| 1009 | }; | 1133 | }; |
| 1010 | 1134 | ||
| @@ -1049,6 +1173,20 @@ static const unsigned mcif_pins[] = { 86, 87, 88, 89, 90, 91, 92, 93, 213, 214, | |||
| 1049 | .reg = PAD_FUNCTION_EN_2, \ | 1173 | .reg = PAD_FUNCTION_EN_2, \ |
| 1050 | .mask = PMX_MCIFALL_2_MASK, \ | 1174 | .mask = PMX_MCIFALL_2_MASK, \ |
| 1051 | .val = PMX_MCIFALL_2_MASK, \ | 1175 | .val = PMX_MCIFALL_2_MASK, \ |
| 1176 | }, { \ | ||
| 1177 | .reg = PAD_DIRECTION_SEL_0, \ | ||
| 1178 | .mask = PMX_MCI_DATA8_15_MASK, \ | ||
| 1179 | .val = PMX_MCI_DATA8_15_MASK, \ | ||
| 1180 | }, { \ | ||
| 1181 | .reg = PAD_DIRECTION_SEL_1, \ | ||
| 1182 | .mask = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ | ||
| 1183 | PMX_NFWPRT2_MASK, \ | ||
| 1184 | .val = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ | ||
| 1185 | PMX_NFWPRT2_MASK, \ | ||
| 1186 | }, { \ | ||
| 1187 | .reg = PAD_DIRECTION_SEL_2, \ | ||
| 1188 | .mask = PMX_MCIFALL_2_MASK, \ | ||
| 1189 | .val = PMX_MCIFALL_2_MASK, \ | ||
| 1052 | } | 1190 | } |
| 1053 | 1191 | ||
| 1054 | /* sdhci device */ | 1192 | /* sdhci device */ |
| @@ -1154,6 +1292,10 @@ static struct spear_muxreg touch_xy_muxreg[] = { | |||
| 1154 | .reg = PAD_FUNCTION_EN_2, | 1292 | .reg = PAD_FUNCTION_EN_2, |
| 1155 | .mask = PMX_TOUCH_XY_MASK, | 1293 | .mask = PMX_TOUCH_XY_MASK, |
| 1156 | .val = PMX_TOUCH_XY_MASK, | 1294 | .val = PMX_TOUCH_XY_MASK, |
| 1295 | }, { | ||
| 1296 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1297 | .mask = PMX_TOUCH_XY_MASK, | ||
| 1298 | .val = PMX_TOUCH_XY_MASK, | ||
| 1157 | }, | 1299 | }, |
| 1158 | }; | 1300 | }; |
| 1159 | 1301 | ||
| @@ -1187,6 +1329,10 @@ static struct spear_muxreg uart1_dis_i2c_muxreg[] = { | |||
| 1187 | .reg = PAD_FUNCTION_EN_0, | 1329 | .reg = PAD_FUNCTION_EN_0, |
| 1188 | .mask = PMX_I2C0_MASK, | 1330 | .mask = PMX_I2C0_MASK, |
| 1189 | .val = 0, | 1331 | .val = 0, |
| 1332 | }, { | ||
| 1333 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1334 | .mask = PMX_I2C0_MASK, | ||
| 1335 | .val = PMX_I2C0_MASK, | ||
| 1190 | }, | 1336 | }, |
| 1191 | }; | 1337 | }; |
| 1192 | 1338 | ||
| @@ -1213,6 +1359,12 @@ static struct spear_muxreg uart1_dis_sd_muxreg[] = { | |||
| 1213 | .mask = PMX_MCIDATA1_MASK | | 1359 | .mask = PMX_MCIDATA1_MASK | |
| 1214 | PMX_MCIDATA2_MASK, | 1360 | PMX_MCIDATA2_MASK, |
| 1215 | .val = 0, | 1361 | .val = 0, |
| 1362 | }, { | ||
| 1363 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1364 | .mask = PMX_MCIDATA1_MASK | | ||
| 1365 | PMX_MCIDATA2_MASK, | ||
| 1366 | .val = PMX_MCIDATA1_MASK | | ||
| 1367 | PMX_MCIDATA2_MASK, | ||
| 1216 | }, | 1368 | }, |
| 1217 | }; | 1369 | }; |
| 1218 | 1370 | ||
| @@ -1246,6 +1398,10 @@ static struct spear_muxreg uart2_3_muxreg[] = { | |||
| 1246 | .reg = PAD_FUNCTION_EN_0, | 1398 | .reg = PAD_FUNCTION_EN_0, |
| 1247 | .mask = PMX_I2S0_MASK, | 1399 | .mask = PMX_I2S0_MASK, |
| 1248 | .val = 0, | 1400 | .val = 0, |
| 1401 | }, { | ||
| 1402 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1403 | .mask = PMX_I2S0_MASK, | ||
| 1404 | .val = PMX_I2S0_MASK, | ||
| 1249 | }, | 1405 | }, |
| 1250 | }; | 1406 | }; |
| 1251 | 1407 | ||
| @@ -1278,6 +1434,10 @@ static struct spear_muxreg uart4_muxreg[] = { | |||
| 1278 | .reg = PAD_FUNCTION_EN_0, | 1434 | .reg = PAD_FUNCTION_EN_0, |
| 1279 | .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, | 1435 | .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, |
| 1280 | .val = 0, | 1436 | .val = 0, |
| 1437 | }, { | ||
| 1438 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1439 | .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, | ||
| 1440 | .val = PMX_I2S0_MASK | PMX_CLCD1_MASK, | ||
| 1281 | }, | 1441 | }, |
| 1282 | }; | 1442 | }; |
| 1283 | 1443 | ||
| @@ -1310,6 +1470,10 @@ static struct spear_muxreg uart5_muxreg[] = { | |||
| 1310 | .reg = PAD_FUNCTION_EN_0, | 1470 | .reg = PAD_FUNCTION_EN_0, |
| 1311 | .mask = PMX_CLCD1_MASK, | 1471 | .mask = PMX_CLCD1_MASK, |
| 1312 | .val = 0, | 1472 | .val = 0, |
| 1473 | }, { | ||
| 1474 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1475 | .mask = PMX_CLCD1_MASK, | ||
| 1476 | .val = PMX_CLCD1_MASK, | ||
| 1313 | }, | 1477 | }, |
| 1314 | }; | 1478 | }; |
| 1315 | 1479 | ||
| @@ -1344,6 +1508,10 @@ static struct spear_muxreg rs485_0_1_tdm_0_1_muxreg[] = { | |||
| 1344 | .reg = PAD_FUNCTION_EN_0, | 1508 | .reg = PAD_FUNCTION_EN_0, |
| 1345 | .mask = PMX_CLCD1_MASK, | 1509 | .mask = PMX_CLCD1_MASK, |
| 1346 | .val = 0, | 1510 | .val = 0, |
| 1511 | }, { | ||
| 1512 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1513 | .mask = PMX_CLCD1_MASK, | ||
| 1514 | .val = PMX_CLCD1_MASK, | ||
| 1347 | }, | 1515 | }, |
| 1348 | }; | 1516 | }; |
| 1349 | 1517 | ||
| @@ -1376,6 +1544,10 @@ static struct spear_muxreg i2c_1_2_muxreg[] = { | |||
| 1376 | .reg = PAD_FUNCTION_EN_0, | 1544 | .reg = PAD_FUNCTION_EN_0, |
| 1377 | .mask = PMX_CLCD1_MASK, | 1545 | .mask = PMX_CLCD1_MASK, |
| 1378 | .val = 0, | 1546 | .val = 0, |
| 1547 | }, { | ||
| 1548 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1549 | .mask = PMX_CLCD1_MASK, | ||
| 1550 | .val = PMX_CLCD1_MASK, | ||
| 1379 | }, | 1551 | }, |
| 1380 | }; | 1552 | }; |
| 1381 | 1553 | ||
| @@ -1409,6 +1581,10 @@ static struct spear_muxreg i2c3_dis_smi_clcd_muxreg[] = { | |||
| 1409 | .reg = PAD_FUNCTION_EN_0, | 1581 | .reg = PAD_FUNCTION_EN_0, |
| 1410 | .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, | 1582 | .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, |
| 1411 | .val = 0, | 1583 | .val = 0, |
| 1584 | }, { | ||
| 1585 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1586 | .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, | ||
| 1587 | .val = PMX_CLCD1_MASK | PMX_SMI_MASK, | ||
| 1412 | }, | 1588 | }, |
| 1413 | }; | 1589 | }; |
| 1414 | 1590 | ||
| @@ -1435,6 +1611,10 @@ static struct spear_muxreg i2c3_dis_sd_i2s0_muxreg[] = { | |||
| 1435 | .reg = PAD_FUNCTION_EN_1, | 1611 | .reg = PAD_FUNCTION_EN_1, |
| 1436 | .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, | 1612 | .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, |
| 1437 | .val = 0, | 1613 | .val = 0, |
| 1614 | }, { | ||
| 1615 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1616 | .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, | ||
| 1617 | .val = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, | ||
| 1438 | }, | 1618 | }, |
| 1439 | }; | 1619 | }; |
| 1440 | 1620 | ||
| @@ -1469,6 +1649,10 @@ static struct spear_muxreg i2c_4_5_dis_smi_muxreg[] = { | |||
| 1469 | .reg = PAD_FUNCTION_EN_0, | 1649 | .reg = PAD_FUNCTION_EN_0, |
| 1470 | .mask = PMX_SMI_MASK, | 1650 | .mask = PMX_SMI_MASK, |
| 1471 | .val = 0, | 1651 | .val = 0, |
| 1652 | }, { | ||
| 1653 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1654 | .mask = PMX_SMI_MASK, | ||
| 1655 | .val = PMX_SMI_MASK, | ||
| 1472 | }, | 1656 | }, |
| 1473 | }; | 1657 | }; |
| 1474 | 1658 | ||
| @@ -1499,6 +1683,14 @@ static struct spear_muxreg i2c4_dis_sd_muxreg[] = { | |||
| 1499 | .reg = PAD_FUNCTION_EN_2, | 1683 | .reg = PAD_FUNCTION_EN_2, |
| 1500 | .mask = PMX_MCIDATA5_MASK, | 1684 | .mask = PMX_MCIDATA5_MASK, |
| 1501 | .val = 0, | 1685 | .val = 0, |
| 1686 | }, { | ||
| 1687 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1688 | .mask = PMX_MCIDATA4_MASK, | ||
| 1689 | .val = PMX_MCIDATA4_MASK, | ||
| 1690 | }, { | ||
| 1691 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1692 | .mask = PMX_MCIDATA5_MASK, | ||
| 1693 | .val = PMX_MCIDATA5_MASK, | ||
| 1502 | }, | 1694 | }, |
| 1503 | }; | 1695 | }; |
| 1504 | 1696 | ||
| @@ -1526,6 +1718,12 @@ static struct spear_muxreg i2c5_dis_sd_muxreg[] = { | |||
| 1526 | .mask = PMX_MCIDATA6_MASK | | 1718 | .mask = PMX_MCIDATA6_MASK | |
| 1527 | PMX_MCIDATA7_MASK, | 1719 | PMX_MCIDATA7_MASK, |
| 1528 | .val = 0, | 1720 | .val = 0, |
| 1721 | }, { | ||
| 1722 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1723 | .mask = PMX_MCIDATA6_MASK | | ||
| 1724 | PMX_MCIDATA7_MASK, | ||
| 1725 | .val = PMX_MCIDATA6_MASK | | ||
| 1726 | PMX_MCIDATA7_MASK, | ||
| 1529 | }, | 1727 | }, |
| 1530 | }; | 1728 | }; |
| 1531 | 1729 | ||
| @@ -1560,6 +1758,10 @@ static struct spear_muxreg i2c_6_7_dis_kbd_muxreg[] = { | |||
| 1560 | .reg = PAD_FUNCTION_EN_1, | 1758 | .reg = PAD_FUNCTION_EN_1, |
| 1561 | .mask = PMX_KBD_ROWCOL25_MASK, | 1759 | .mask = PMX_KBD_ROWCOL25_MASK, |
| 1562 | .val = 0, | 1760 | .val = 0, |
| 1761 | }, { | ||
| 1762 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1763 | .mask = PMX_KBD_ROWCOL25_MASK, | ||
| 1764 | .val = PMX_KBD_ROWCOL25_MASK, | ||
| 1563 | }, | 1765 | }, |
| 1564 | }; | 1766 | }; |
| 1565 | 1767 | ||
| @@ -1587,6 +1789,12 @@ static struct spear_muxreg i2c6_dis_sd_muxreg[] = { | |||
| 1587 | .mask = PMX_MCIIORDRE_MASK | | 1789 | .mask = PMX_MCIIORDRE_MASK | |
| 1588 | PMX_MCIIOWRWE_MASK, | 1790 | PMX_MCIIOWRWE_MASK, |
| 1589 | .val = 0, | 1791 | .val = 0, |
| 1792 | }, { | ||
| 1793 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1794 | .mask = PMX_MCIIORDRE_MASK | | ||
| 1795 | PMX_MCIIOWRWE_MASK, | ||
| 1796 | .val = PMX_MCIIORDRE_MASK | | ||
| 1797 | PMX_MCIIOWRWE_MASK, | ||
| 1590 | }, | 1798 | }, |
| 1591 | }; | 1799 | }; |
| 1592 | 1800 | ||
| @@ -1613,6 +1821,12 @@ static struct spear_muxreg i2c7_dis_sd_muxreg[] = { | |||
| 1613 | .mask = PMX_MCIRESETCF_MASK | | 1821 | .mask = PMX_MCIRESETCF_MASK | |
| 1614 | PMX_MCICS0CE_MASK, | 1822 | PMX_MCICS0CE_MASK, |
| 1615 | .val = 0, | 1823 | .val = 0, |
| 1824 | }, { | ||
| 1825 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1826 | .mask = PMX_MCIRESETCF_MASK | | ||
| 1827 | PMX_MCICS0CE_MASK, | ||
| 1828 | .val = PMX_MCIRESETCF_MASK | | ||
| 1829 | PMX_MCICS0CE_MASK, | ||
| 1616 | }, | 1830 | }, |
| 1617 | }; | 1831 | }; |
| 1618 | 1832 | ||
| @@ -1651,6 +1865,14 @@ static struct spear_muxreg can0_dis_nor_muxreg[] = { | |||
| 1651 | .reg = PAD_FUNCTION_EN_1, | 1865 | .reg = PAD_FUNCTION_EN_1, |
| 1652 | .mask = PMX_NFRSTPWDWN3_MASK, | 1866 | .mask = PMX_NFRSTPWDWN3_MASK, |
| 1653 | .val = 0, | 1867 | .val = 0, |
| 1868 | }, { | ||
| 1869 | .reg = PAD_DIRECTION_SEL_0, | ||
| 1870 | .mask = PMX_NFRSTPWDWN2_MASK, | ||
| 1871 | .val = PMX_NFRSTPWDWN2_MASK, | ||
| 1872 | }, { | ||
| 1873 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1874 | .mask = PMX_NFRSTPWDWN3_MASK, | ||
| 1875 | .val = PMX_NFRSTPWDWN3_MASK, | ||
| 1654 | }, | 1876 | }, |
| 1655 | }; | 1877 | }; |
| 1656 | 1878 | ||
| @@ -1677,6 +1899,10 @@ static struct spear_muxreg can0_dis_sd_muxreg[] = { | |||
| 1677 | .reg = PAD_FUNCTION_EN_2, | 1899 | .reg = PAD_FUNCTION_EN_2, |
| 1678 | .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, | 1900 | .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, |
| 1679 | .val = 0, | 1901 | .val = 0, |
| 1902 | }, { | ||
| 1903 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1904 | .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, | ||
| 1905 | .val = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, | ||
| 1680 | }, | 1906 | }, |
| 1681 | }; | 1907 | }; |
| 1682 | 1908 | ||
| @@ -1711,6 +1937,10 @@ static struct spear_muxreg can1_dis_sd_muxreg[] = { | |||
| 1711 | .reg = PAD_FUNCTION_EN_2, | 1937 | .reg = PAD_FUNCTION_EN_2, |
| 1712 | .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, | 1938 | .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, |
| 1713 | .val = 0, | 1939 | .val = 0, |
| 1940 | }, { | ||
| 1941 | .reg = PAD_DIRECTION_SEL_2, | ||
| 1942 | .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, | ||
| 1943 | .val = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, | ||
| 1714 | }, | 1944 | }, |
| 1715 | }; | 1945 | }; |
| 1716 | 1946 | ||
| @@ -1737,6 +1967,10 @@ static struct spear_muxreg can1_dis_kbd_muxreg[] = { | |||
| 1737 | .reg = PAD_FUNCTION_EN_1, | 1967 | .reg = PAD_FUNCTION_EN_1, |
| 1738 | .mask = PMX_KBD_ROWCOL25_MASK, | 1968 | .mask = PMX_KBD_ROWCOL25_MASK, |
| 1739 | .val = 0, | 1969 | .val = 0, |
| 1970 | }, { | ||
| 1971 | .reg = PAD_DIRECTION_SEL_1, | ||
| 1972 | .mask = PMX_KBD_ROWCOL25_MASK, | ||
| 1973 | .val = PMX_KBD_ROWCOL25_MASK, | ||
| 1740 | }, | 1974 | }, |
| 1741 | }; | 1975 | }; |
| 1742 | 1976 | ||
| @@ -1763,29 +1997,64 @@ static struct spear_function can1_function = { | |||
| 1763 | .ngroups = ARRAY_SIZE(can1_grps), | 1997 | .ngroups = ARRAY_SIZE(can1_grps), |
| 1764 | }; | 1998 | }; |
| 1765 | 1999 | ||
| 1766 | /* Pad multiplexing for pci device */ | 2000 | /* Pad multiplexing for (ras-ip) pci device */ |
| 1767 | static const unsigned pci_sata_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, | 2001 | static const unsigned pci_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, |
| 1768 | 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, | 2002 | 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, |
| 1769 | 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, | 2003 | 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, |
| 1770 | 55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }; | 2004 | 55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }; |
| 1771 | #define PCI_SATA_MUXREG \ | ||
| 1772 | { \ | ||
| 1773 | .reg = PAD_FUNCTION_EN_0, \ | ||
| 1774 | .mask = PMX_MCI_DATA8_15_MASK, \ | ||
| 1775 | .val = 0, \ | ||
| 1776 | }, { \ | ||
| 1777 | .reg = PAD_FUNCTION_EN_1, \ | ||
| 1778 | .mask = PMX_PCI_REG1_MASK, \ | ||
| 1779 | .val = 0, \ | ||
| 1780 | }, { \ | ||
| 1781 | .reg = PAD_FUNCTION_EN_2, \ | ||
| 1782 | .mask = PMX_PCI_REG2_MASK, \ | ||
| 1783 | .val = 0, \ | ||
| 1784 | } | ||
| 1785 | 2005 | ||
| 1786 | /* pad multiplexing for pcie0 device */ | 2006 | static struct spear_muxreg pci_muxreg[] = { |
| 2007 | { | ||
| 2008 | .reg = PAD_FUNCTION_EN_0, | ||
| 2009 | .mask = PMX_MCI_DATA8_15_MASK, | ||
| 2010 | .val = 0, | ||
| 2011 | }, { | ||
| 2012 | .reg = PAD_FUNCTION_EN_1, | ||
| 2013 | .mask = PMX_PCI_REG1_MASK, | ||
| 2014 | .val = 0, | ||
| 2015 | }, { | ||
| 2016 | .reg = PAD_FUNCTION_EN_2, | ||
| 2017 | .mask = PMX_PCI_REG2_MASK, | ||
| 2018 | .val = 0, | ||
| 2019 | }, { | ||
| 2020 | .reg = PAD_DIRECTION_SEL_0, | ||
| 2021 | .mask = PMX_MCI_DATA8_15_MASK, | ||
| 2022 | .val = PMX_MCI_DATA8_15_MASK, | ||
| 2023 | }, { | ||
| 2024 | .reg = PAD_DIRECTION_SEL_1, | ||
| 2025 | .mask = PMX_PCI_REG1_MASK, | ||
| 2026 | .val = PMX_PCI_REG1_MASK, | ||
| 2027 | }, { | ||
| 2028 | .reg = PAD_DIRECTION_SEL_2, | ||
| 2029 | .mask = PMX_PCI_REG2_MASK, | ||
| 2030 | .val = PMX_PCI_REG2_MASK, | ||
| 2031 | }, | ||
| 2032 | }; | ||
| 2033 | |||
| 2034 | static struct spear_modemux pci_modemux[] = { | ||
| 2035 | { | ||
| 2036 | .muxregs = pci_muxreg, | ||
| 2037 | .nmuxregs = ARRAY_SIZE(pci_muxreg), | ||
| 2038 | }, | ||
| 2039 | }; | ||
| 2040 | |||
| 2041 | static struct spear_pingroup pci_pingroup = { | ||
| 2042 | .name = "pci_grp", | ||
| 2043 | .pins = pci_pins, | ||
| 2044 | .npins = ARRAY_SIZE(pci_pins), | ||
| 2045 | .modemuxs = pci_modemux, | ||
| 2046 | .nmodemuxs = ARRAY_SIZE(pci_modemux), | ||
| 2047 | }; | ||
| 2048 | |||
| 2049 | static const char *const pci_grps[] = { "pci_grp" }; | ||
| 2050 | static struct spear_function pci_function = { | ||
| 2051 | .name = "pci", | ||
| 2052 | .groups = pci_grps, | ||
| 2053 | .ngroups = ARRAY_SIZE(pci_grps), | ||
| 2054 | }; | ||
| 2055 | |||
| 2056 | /* pad multiplexing for (fix-part) pcie0 device */ | ||
| 1787 | static struct spear_muxreg pcie0_muxreg[] = { | 2057 | static struct spear_muxreg pcie0_muxreg[] = { |
| 1788 | PCI_SATA_MUXREG, | ||
| 1789 | { | 2058 | { |
| 1790 | .reg = PCIE_SATA_CFG, | 2059 | .reg = PCIE_SATA_CFG, |
| 1791 | .mask = PCIE_CFG_VAL(0), | 2060 | .mask = PCIE_CFG_VAL(0), |
| @@ -1802,15 +2071,12 @@ static struct spear_modemux pcie0_modemux[] = { | |||
| 1802 | 2071 | ||
| 1803 | static struct spear_pingroup pcie0_pingroup = { | 2072 | static struct spear_pingroup pcie0_pingroup = { |
| 1804 | .name = "pcie0_grp", | 2073 | .name = "pcie0_grp", |
| 1805 | .pins = pci_sata_pins, | ||
| 1806 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1807 | .modemuxs = pcie0_modemux, | 2074 | .modemuxs = pcie0_modemux, |
| 1808 | .nmodemuxs = ARRAY_SIZE(pcie0_modemux), | 2075 | .nmodemuxs = ARRAY_SIZE(pcie0_modemux), |
| 1809 | }; | 2076 | }; |
| 1810 | 2077 | ||
| 1811 | /* pad multiplexing for pcie1 device */ | 2078 | /* pad multiplexing for (fix-part) pcie1 device */ |
| 1812 | static struct spear_muxreg pcie1_muxreg[] = { | 2079 | static struct spear_muxreg pcie1_muxreg[] = { |
| 1813 | PCI_SATA_MUXREG, | ||
| 1814 | { | 2080 | { |
| 1815 | .reg = PCIE_SATA_CFG, | 2081 | .reg = PCIE_SATA_CFG, |
| 1816 | .mask = PCIE_CFG_VAL(1), | 2082 | .mask = PCIE_CFG_VAL(1), |
| @@ -1827,15 +2093,12 @@ static struct spear_modemux pcie1_modemux[] = { | |||
| 1827 | 2093 | ||
| 1828 | static struct spear_pingroup pcie1_pingroup = { | 2094 | static struct spear_pingroup pcie1_pingroup = { |
| 1829 | .name = "pcie1_grp", | 2095 | .name = "pcie1_grp", |
| 1830 | .pins = pci_sata_pins, | ||
| 1831 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1832 | .modemuxs = pcie1_modemux, | 2096 | .modemuxs = pcie1_modemux, |
| 1833 | .nmodemuxs = ARRAY_SIZE(pcie1_modemux), | 2097 | .nmodemuxs = ARRAY_SIZE(pcie1_modemux), |
| 1834 | }; | 2098 | }; |
| 1835 | 2099 | ||
| 1836 | /* pad multiplexing for pcie2 device */ | 2100 | /* pad multiplexing for (fix-part) pcie2 device */ |
| 1837 | static struct spear_muxreg pcie2_muxreg[] = { | 2101 | static struct spear_muxreg pcie2_muxreg[] = { |
| 1838 | PCI_SATA_MUXREG, | ||
| 1839 | { | 2102 | { |
| 1840 | .reg = PCIE_SATA_CFG, | 2103 | .reg = PCIE_SATA_CFG, |
| 1841 | .mask = PCIE_CFG_VAL(2), | 2104 | .mask = PCIE_CFG_VAL(2), |
| @@ -1852,22 +2115,20 @@ static struct spear_modemux pcie2_modemux[] = { | |||
| 1852 | 2115 | ||
| 1853 | static struct spear_pingroup pcie2_pingroup = { | 2116 | static struct spear_pingroup pcie2_pingroup = { |
| 1854 | .name = "pcie2_grp", | 2117 | .name = "pcie2_grp", |
| 1855 | .pins = pci_sata_pins, | ||
| 1856 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1857 | .modemuxs = pcie2_modemux, | 2118 | .modemuxs = pcie2_modemux, |
| 1858 | .nmodemuxs = ARRAY_SIZE(pcie2_modemux), | 2119 | .nmodemuxs = ARRAY_SIZE(pcie2_modemux), |
| 1859 | }; | 2120 | }; |
| 1860 | 2121 | ||
| 1861 | static const char *const pci_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" }; | 2122 | static const char *const pcie_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" |
| 1862 | static struct spear_function pci_function = { | 2123 | }; |
| 1863 | .name = "pci", | 2124 | static struct spear_function pcie_function = { |
| 1864 | .groups = pci_grps, | 2125 | .name = "pci_express", |
| 1865 | .ngroups = ARRAY_SIZE(pci_grps), | 2126 | .groups = pcie_grps, |
| 2127 | .ngroups = ARRAY_SIZE(pcie_grps), | ||
| 1866 | }; | 2128 | }; |
| 1867 | 2129 | ||
| 1868 | /* pad multiplexing for sata0 device */ | 2130 | /* pad multiplexing for sata0 device */ |
| 1869 | static struct spear_muxreg sata0_muxreg[] = { | 2131 | static struct spear_muxreg sata0_muxreg[] = { |
| 1870 | PCI_SATA_MUXREG, | ||
| 1871 | { | 2132 | { |
| 1872 | .reg = PCIE_SATA_CFG, | 2133 | .reg = PCIE_SATA_CFG, |
| 1873 | .mask = SATA_CFG_VAL(0), | 2134 | .mask = SATA_CFG_VAL(0), |
| @@ -1884,15 +2145,12 @@ static struct spear_modemux sata0_modemux[] = { | |||
| 1884 | 2145 | ||
| 1885 | static struct spear_pingroup sata0_pingroup = { | 2146 | static struct spear_pingroup sata0_pingroup = { |
| 1886 | .name = "sata0_grp", | 2147 | .name = "sata0_grp", |
| 1887 | .pins = pci_sata_pins, | ||
| 1888 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1889 | .modemuxs = sata0_modemux, | 2148 | .modemuxs = sata0_modemux, |
| 1890 | .nmodemuxs = ARRAY_SIZE(sata0_modemux), | 2149 | .nmodemuxs = ARRAY_SIZE(sata0_modemux), |
| 1891 | }; | 2150 | }; |
| 1892 | 2151 | ||
| 1893 | /* pad multiplexing for sata1 device */ | 2152 | /* pad multiplexing for sata1 device */ |
| 1894 | static struct spear_muxreg sata1_muxreg[] = { | 2153 | static struct spear_muxreg sata1_muxreg[] = { |
| 1895 | PCI_SATA_MUXREG, | ||
| 1896 | { | 2154 | { |
| 1897 | .reg = PCIE_SATA_CFG, | 2155 | .reg = PCIE_SATA_CFG, |
| 1898 | .mask = SATA_CFG_VAL(1), | 2156 | .mask = SATA_CFG_VAL(1), |
| @@ -1909,15 +2167,12 @@ static struct spear_modemux sata1_modemux[] = { | |||
| 1909 | 2167 | ||
| 1910 | static struct spear_pingroup sata1_pingroup = { | 2168 | static struct spear_pingroup sata1_pingroup = { |
| 1911 | .name = "sata1_grp", | 2169 | .name = "sata1_grp", |
| 1912 | .pins = pci_sata_pins, | ||
| 1913 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1914 | .modemuxs = sata1_modemux, | 2170 | .modemuxs = sata1_modemux, |
| 1915 | .nmodemuxs = ARRAY_SIZE(sata1_modemux), | 2171 | .nmodemuxs = ARRAY_SIZE(sata1_modemux), |
| 1916 | }; | 2172 | }; |
| 1917 | 2173 | ||
| 1918 | /* pad multiplexing for sata2 device */ | 2174 | /* pad multiplexing for sata2 device */ |
| 1919 | static struct spear_muxreg sata2_muxreg[] = { | 2175 | static struct spear_muxreg sata2_muxreg[] = { |
| 1920 | PCI_SATA_MUXREG, | ||
| 1921 | { | 2176 | { |
| 1922 | .reg = PCIE_SATA_CFG, | 2177 | .reg = PCIE_SATA_CFG, |
| 1923 | .mask = SATA_CFG_VAL(2), | 2178 | .mask = SATA_CFG_VAL(2), |
| @@ -1934,8 +2189,6 @@ static struct spear_modemux sata2_modemux[] = { | |||
| 1934 | 2189 | ||
| 1935 | static struct spear_pingroup sata2_pingroup = { | 2190 | static struct spear_pingroup sata2_pingroup = { |
| 1936 | .name = "sata2_grp", | 2191 | .name = "sata2_grp", |
| 1937 | .pins = pci_sata_pins, | ||
| 1938 | .npins = ARRAY_SIZE(pci_sata_pins), | ||
| 1939 | .modemuxs = sata2_modemux, | 2192 | .modemuxs = sata2_modemux, |
| 1940 | .nmodemuxs = ARRAY_SIZE(sata2_modemux), | 2193 | .nmodemuxs = ARRAY_SIZE(sata2_modemux), |
| 1941 | }; | 2194 | }; |
| @@ -1957,6 +2210,14 @@ static struct spear_muxreg ssp1_dis_kbd_muxreg[] = { | |||
| 1957 | PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | | 2210 | PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | |
| 1958 | PMX_NFCE2_MASK, | 2211 | PMX_NFCE2_MASK, |
| 1959 | .val = 0, | 2212 | .val = 0, |
| 2213 | }, { | ||
| 2214 | .reg = PAD_DIRECTION_SEL_1, | ||
| 2215 | .mask = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | | ||
| 2216 | PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | | ||
| 2217 | PMX_NFCE2_MASK, | ||
| 2218 | .val = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | | ||
| 2219 | PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | | ||
| 2220 | PMX_NFCE2_MASK, | ||
| 1960 | }, | 2221 | }, |
| 1961 | }; | 2222 | }; |
| 1962 | 2223 | ||
| @@ -1983,6 +2244,12 @@ static struct spear_muxreg ssp1_dis_sd_muxreg[] = { | |||
| 1983 | .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | | 2244 | .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | |
| 1984 | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, | 2245 | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, |
| 1985 | .val = 0, | 2246 | .val = 0, |
| 2247 | }, { | ||
| 2248 | .reg = PAD_DIRECTION_SEL_2, | ||
| 2249 | .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | | ||
| 2250 | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, | ||
| 2251 | .val = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | | ||
| 2252 | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, | ||
| 1986 | }, | 2253 | }, |
| 1987 | }; | 2254 | }; |
| 1988 | 2255 | ||
| @@ -2017,6 +2284,12 @@ static struct spear_muxreg gpt64_muxreg[] = { | |||
| 2017 | .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK | 2284 | .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK |
| 2018 | | PMX_MCILEDS_MASK, | 2285 | | PMX_MCILEDS_MASK, |
| 2019 | .val = 0, | 2286 | .val = 0, |
| 2287 | }, { | ||
| 2288 | .reg = PAD_DIRECTION_SEL_2, | ||
| 2289 | .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK | ||
| 2290 | | PMX_MCILEDS_MASK, | ||
| 2291 | .val = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK | ||
| 2292 | | PMX_MCILEDS_MASK, | ||
| 2020 | }, | 2293 | }, |
| 2021 | }; | 2294 | }; |
| 2022 | 2295 | ||
| @@ -2093,6 +2366,7 @@ static struct spear_pingroup *spear1310_pingroups[] = { | |||
| 2093 | &can0_dis_sd_pingroup, | 2366 | &can0_dis_sd_pingroup, |
| 2094 | &can1_dis_sd_pingroup, | 2367 | &can1_dis_sd_pingroup, |
| 2095 | &can1_dis_kbd_pingroup, | 2368 | &can1_dis_kbd_pingroup, |
| 2369 | &pci_pingroup, | ||
| 2096 | &pcie0_pingroup, | 2370 | &pcie0_pingroup, |
| 2097 | &pcie1_pingroup, | 2371 | &pcie1_pingroup, |
| 2098 | &pcie2_pingroup, | 2372 | &pcie2_pingroup, |
| @@ -2138,6 +2412,7 @@ static struct spear_function *spear1310_functions[] = { | |||
| 2138 | &can0_function, | 2412 | &can0_function, |
| 2139 | &can1_function, | 2413 | &can1_function, |
| 2140 | &pci_function, | 2414 | &pci_function, |
| 2415 | &pcie_function, | ||
| 2141 | &sata_function, | 2416 | &sata_function, |
| 2142 | &ssp1_function, | 2417 | &ssp1_function, |
| 2143 | &gpt64_function, | 2418 | &gpt64_function, |
diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c index a0eb057e55bd..0606b8cf3f2c 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/drivers/pinctrl/spear/pinctrl-spear1340.c | |||
| @@ -213,7 +213,7 @@ static const struct pinctrl_pin_desc spear1340_pins[] = { | |||
| 213 | * Pad multiplexing for making all pads as gpio's. This is done to override the | 213 | * Pad multiplexing for making all pads as gpio's. This is done to override the |
| 214 | * values passed from bootloader and start from scratch. | 214 | * values passed from bootloader and start from scratch. |
| 215 | */ | 215 | */ |
| 216 | static const unsigned pads_as_gpio_pins[] = { 251 }; | 216 | static const unsigned pads_as_gpio_pins[] = { 12, 88, 89, 251 }; |
| 217 | static struct spear_muxreg pads_as_gpio_muxreg[] = { | 217 | static struct spear_muxreg pads_as_gpio_muxreg[] = { |
| 218 | { | 218 | { |
| 219 | .reg = PAD_FUNCTION_EN_1, | 219 | .reg = PAD_FUNCTION_EN_1, |
| @@ -1692,7 +1692,43 @@ static struct spear_pingroup clcd_pingroup = { | |||
| 1692 | .nmodemuxs = ARRAY_SIZE(clcd_modemux), | 1692 | .nmodemuxs = ARRAY_SIZE(clcd_modemux), |
| 1693 | }; | 1693 | }; |
| 1694 | 1694 | ||
| 1695 | static const char *const clcd_grps[] = { "clcd_grp" }; | 1695 | /* Disable cld runtime to save panel damage */ |
| 1696 | static struct spear_muxreg clcd_sleep_muxreg[] = { | ||
| 1697 | { | ||
| 1698 | .reg = PAD_SHARED_IP_EN_1, | ||
| 1699 | .mask = ARM_TRACE_MASK | MIPHY_DBG_MASK, | ||
| 1700 | .val = 0, | ||
| 1701 | }, { | ||
| 1702 | .reg = PAD_FUNCTION_EN_5, | ||
| 1703 | .mask = CLCD_REG4_MASK | CLCD_AND_ARM_TRACE_REG4_MASK, | ||
| 1704 | .val = 0x0, | ||
| 1705 | }, { | ||
| 1706 | .reg = PAD_FUNCTION_EN_6, | ||
| 1707 | .mask = CLCD_AND_ARM_TRACE_REG5_MASK, | ||
| 1708 | .val = 0x0, | ||
| 1709 | }, { | ||
| 1710 | .reg = PAD_FUNCTION_EN_7, | ||
| 1711 | .mask = CLCD_AND_ARM_TRACE_REG6_MASK, | ||
| 1712 | .val = 0x0, | ||
| 1713 | }, | ||
| 1714 | }; | ||
| 1715 | |||
| 1716 | static struct spear_modemux clcd_sleep_modemux[] = { | ||
| 1717 | { | ||
| 1718 | .muxregs = clcd_sleep_muxreg, | ||
| 1719 | .nmuxregs = ARRAY_SIZE(clcd_sleep_muxreg), | ||
| 1720 | }, | ||
| 1721 | }; | ||
| 1722 | |||
| 1723 | static struct spear_pingroup clcd_sleep_pingroup = { | ||
| 1724 | .name = "clcd_sleep_grp", | ||
| 1725 | .pins = clcd_pins, | ||
| 1726 | .npins = ARRAY_SIZE(clcd_pins), | ||
| 1727 | .modemuxs = clcd_sleep_modemux, | ||
| 1728 | .nmodemuxs = ARRAY_SIZE(clcd_sleep_modemux), | ||
| 1729 | }; | ||
| 1730 | |||
| 1731 | static const char *const clcd_grps[] = { "clcd_grp", "clcd_sleep_grp" }; | ||
| 1696 | static struct spear_function clcd_function = { | 1732 | static struct spear_function clcd_function = { |
| 1697 | .name = "clcd", | 1733 | .name = "clcd", |
| 1698 | .groups = clcd_grps, | 1734 | .groups = clcd_grps, |
| @@ -1893,6 +1929,7 @@ static struct spear_pingroup *spear1340_pingroups[] = { | |||
| 1893 | &sdhci_pingroup, | 1929 | &sdhci_pingroup, |
| 1894 | &cf_pingroup, | 1930 | &cf_pingroup, |
| 1895 | &xd_pingroup, | 1931 | &xd_pingroup, |
| 1932 | &clcd_sleep_pingroup, | ||
| 1896 | &clcd_pingroup, | 1933 | &clcd_pingroup, |
| 1897 | &arm_trace_pingroup, | 1934 | &arm_trace_pingroup, |
| 1898 | &miphy_dbg_pingroup, | 1935 | &miphy_dbg_pingroup, |
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c index 020b1e0bdb3e..ca47b0e50780 100644 --- a/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/drivers/pinctrl/spear/pinctrl-spear320.c | |||
| @@ -2240,6 +2240,10 @@ static struct spear_muxreg pwm2_pin_34_muxreg[] = { | |||
| 2240 | .mask = PMX_SSP_CS_MASK, | 2240 | .mask = PMX_SSP_CS_MASK, |
| 2241 | .val = 0, | 2241 | .val = 0, |
| 2242 | }, { | 2242 | }, { |
| 2243 | .reg = MODE_CONFIG_REG, | ||
| 2244 | .mask = PMX_PWM_MASK, | ||
| 2245 | .val = PMX_PWM_MASK, | ||
| 2246 | }, { | ||
| 2243 | .reg = IP_SEL_PAD_30_39_REG, | 2247 | .reg = IP_SEL_PAD_30_39_REG, |
| 2244 | .mask = PMX_PL_34_MASK, | 2248 | .mask = PMX_PL_34_MASK, |
| 2245 | .val = PMX_PWM2_PL_34_VAL, | 2249 | .val = PMX_PWM2_PL_34_VAL, |
| @@ -2956,9 +2960,9 @@ static struct spear_function mii2_function = { | |||
| 2956 | }; | 2960 | }; |
| 2957 | 2961 | ||
| 2958 | /* Pad multiplexing for cadence mii 1_2 as smii or rmii device */ | 2962 | /* Pad multiplexing for cadence mii 1_2 as smii or rmii device */ |
| 2959 | static const unsigned smii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, | 2963 | static const unsigned rmii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, |
| 2960 | 21, 22, 23, 24, 25, 26, 27 }; | 2964 | 21, 22, 23, 24, 25, 26, 27 }; |
| 2961 | static const unsigned rmii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; | 2965 | static const unsigned smii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; |
| 2962 | static struct spear_muxreg mii0_1_muxreg[] = { | 2966 | static struct spear_muxreg mii0_1_muxreg[] = { |
| 2963 | { | 2967 | { |
| 2964 | .reg = PMX_CONFIG_REG, | 2968 | .reg = PMX_CONFIG_REG, |
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h index 31f44347f17c..7860b36053c4 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.h +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "pinctrl-spear.h" | 15 | #include "pinctrl-spear.h" |
| 16 | 16 | ||
| 17 | /* pad mux declarations */ | 17 | /* pad mux declarations */ |
| 18 | #define PMX_PWM_MASK (1 << 16) | ||
| 18 | #define PMX_FIRDA_MASK (1 << 14) | 19 | #define PMX_FIRDA_MASK (1 << 14) |
| 19 | #define PMX_I2C_MASK (1 << 13) | 20 | #define PMX_I2C_MASK (1 << 13) |
| 20 | #define PMX_SSP_CS_MASK (1 << 12) | 21 | #define PMX_SSP_CS_MASK (1 << 12) |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5c4829cba6a6..e872c8be080e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -1381,22 +1381,14 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) | |||
| 1381 | } | 1381 | } |
| 1382 | EXPORT_SYMBOL_GPL(regulator_get_exclusive); | 1382 | EXPORT_SYMBOL_GPL(regulator_get_exclusive); |
| 1383 | 1383 | ||
| 1384 | /** | 1384 | /* Locks held by regulator_put() */ |
| 1385 | * regulator_put - "free" the regulator source | 1385 | static void _regulator_put(struct regulator *regulator) |
| 1386 | * @regulator: regulator source | ||
| 1387 | * | ||
| 1388 | * Note: drivers must ensure that all regulator_enable calls made on this | ||
| 1389 | * regulator source are balanced by regulator_disable calls prior to calling | ||
| 1390 | * this function. | ||
| 1391 | */ | ||
| 1392 | void regulator_put(struct regulator *regulator) | ||
| 1393 | { | 1386 | { |
| 1394 | struct regulator_dev *rdev; | 1387 | struct regulator_dev *rdev; |
| 1395 | 1388 | ||
| 1396 | if (regulator == NULL || IS_ERR(regulator)) | 1389 | if (regulator == NULL || IS_ERR(regulator)) |
| 1397 | return; | 1390 | return; |
| 1398 | 1391 | ||
| 1399 | mutex_lock(®ulator_list_mutex); | ||
| 1400 | rdev = regulator->rdev; | 1392 | rdev = regulator->rdev; |
| 1401 | 1393 | ||
| 1402 | debugfs_remove_recursive(regulator->debugfs); | 1394 | debugfs_remove_recursive(regulator->debugfs); |
| @@ -1412,6 +1404,20 @@ void regulator_put(struct regulator *regulator) | |||
| 1412 | rdev->exclusive = 0; | 1404 | rdev->exclusive = 0; |
| 1413 | 1405 | ||
| 1414 | module_put(rdev->owner); | 1406 | module_put(rdev->owner); |
| 1407 | } | ||
| 1408 | |||
| 1409 | /** | ||
| 1410 | * regulator_put - "free" the regulator source | ||
| 1411 | * @regulator: regulator source | ||
| 1412 | * | ||
| 1413 | * Note: drivers must ensure that all regulator_enable calls made on this | ||
| 1414 | * regulator source are balanced by regulator_disable calls prior to calling | ||
| 1415 | * this function. | ||
| 1416 | */ | ||
| 1417 | void regulator_put(struct regulator *regulator) | ||
| 1418 | { | ||
| 1419 | mutex_lock(®ulator_list_mutex); | ||
| 1420 | _regulator_put(regulator); | ||
| 1415 | mutex_unlock(®ulator_list_mutex); | 1421 | mutex_unlock(®ulator_list_mutex); |
| 1416 | } | 1422 | } |
| 1417 | EXPORT_SYMBOL_GPL(regulator_put); | 1423 | EXPORT_SYMBOL_GPL(regulator_put); |
| @@ -1974,7 +1980,7 @@ int regulator_is_supported_voltage(struct regulator *regulator, | |||
| 1974 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { | 1980 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { |
| 1975 | ret = regulator_get_voltage(regulator); | 1981 | ret = regulator_get_voltage(regulator); |
| 1976 | if (ret >= 0) | 1982 | if (ret >= 0) |
| 1977 | return (min_uV >= ret && ret <= max_uV); | 1983 | return (min_uV <= ret && ret <= max_uV); |
| 1978 | else | 1984 | else |
| 1979 | return ret; | 1985 | return ret; |
| 1980 | } | 1986 | } |
| @@ -3365,7 +3371,7 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
| 3365 | if (ret != 0) { | 3371 | if (ret != 0) { |
| 3366 | rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", | 3372 | rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", |
| 3367 | config->ena_gpio, ret); | 3373 | config->ena_gpio, ret); |
| 3368 | goto clean; | 3374 | goto wash; |
| 3369 | } | 3375 | } |
| 3370 | 3376 | ||
| 3371 | rdev->ena_gpio = config->ena_gpio; | 3377 | rdev->ena_gpio = config->ena_gpio; |
| @@ -3445,10 +3451,11 @@ unset_supplies: | |||
| 3445 | 3451 | ||
| 3446 | scrub: | 3452 | scrub: |
| 3447 | if (rdev->supply) | 3453 | if (rdev->supply) |
| 3448 | regulator_put(rdev->supply); | 3454 | _regulator_put(rdev->supply); |
| 3449 | if (rdev->ena_gpio) | 3455 | if (rdev->ena_gpio) |
| 3450 | gpio_free(rdev->ena_gpio); | 3456 | gpio_free(rdev->ena_gpio); |
| 3451 | kfree(rdev->constraints); | 3457 | kfree(rdev->constraints); |
| 3458 | wash: | ||
| 3452 | device_unregister(&rdev->dev); | 3459 | device_unregister(&rdev->dev); |
| 3453 | /* device core frees rdev */ | 3460 | /* device core frees rdev */ |
| 3454 | rdev = ERR_PTR(ret); | 3461 | rdev = ERR_PTR(ret); |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 9ffb6d5f17aa..4ed343e4eb41 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
| @@ -44,7 +44,6 @@ | |||
| 44 | #define RAW3215_NR_CCWS 3 | 44 | #define RAW3215_NR_CCWS 3 |
| 45 | #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ | 45 | #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ |
| 46 | 46 | ||
| 47 | #define RAW3215_FIXED 1 /* 3215 console device is not be freed */ | ||
| 48 | #define RAW3215_WORKING 4 /* set if a request is being worked on */ | 47 | #define RAW3215_WORKING 4 /* set if a request is being worked on */ |
| 49 | #define RAW3215_THROTTLED 8 /* set if reading is disabled */ | 48 | #define RAW3215_THROTTLED 8 /* set if reading is disabled */ |
| 50 | #define RAW3215_STOPPED 16 /* set if writing is disabled */ | 49 | #define RAW3215_STOPPED 16 /* set if writing is disabled */ |
| @@ -339,8 +338,10 @@ static void raw3215_wakeup(unsigned long data) | |||
| 339 | struct tty_struct *tty; | 338 | struct tty_struct *tty; |
| 340 | 339 | ||
| 341 | tty = tty_port_tty_get(&raw->port); | 340 | tty = tty_port_tty_get(&raw->port); |
| 342 | tty_wakeup(tty); | 341 | if (tty) { |
| 343 | tty_kref_put(tty); | 342 | tty_wakeup(tty); |
| 343 | tty_kref_put(tty); | ||
| 344 | } | ||
| 344 | } | 345 | } |
| 345 | 346 | ||
| 346 | /* | 347 | /* |
| @@ -629,8 +630,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) | |||
| 629 | DECLARE_WAITQUEUE(wait, current); | 630 | DECLARE_WAITQUEUE(wait, current); |
| 630 | unsigned long flags; | 631 | unsigned long flags; |
| 631 | 632 | ||
| 632 | if (!(raw->port.flags & ASYNC_INITIALIZED) || | 633 | if (!(raw->port.flags & ASYNC_INITIALIZED)) |
| 633 | (raw->flags & RAW3215_FIXED)) | ||
| 634 | return; | 634 | return; |
| 635 | /* Wait for outstanding requests, then free irq */ | 635 | /* Wait for outstanding requests, then free irq */ |
| 636 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); | 636 | spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); |
| @@ -926,8 +926,6 @@ static int __init con3215_init(void) | |||
| 926 | dev_set_drvdata(&cdev->dev, raw); | 926 | dev_set_drvdata(&cdev->dev, raw); |
| 927 | cdev->handler = raw3215_irq; | 927 | cdev->handler = raw3215_irq; |
| 928 | 928 | ||
| 929 | raw->flags |= RAW3215_FIXED; | ||
| 930 | |||
| 931 | /* Request the console irq */ | 929 | /* Request the console irq */ |
| 932 | if (raw3215_startup(raw) != 0) { | 930 | if (raw3215_startup(raw) != 0) { |
| 933 | raw3215_free_info(raw); | 931 | raw3215_free_info(raw); |
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 33bb4d891e16..4af3dfe70ef5 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h | |||
| @@ -112,9 +112,6 @@ extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); | |||
| 112 | extern void css_reiterate_subchannels(void); | 112 | extern void css_reiterate_subchannels(void); |
| 113 | void css_update_ssd_info(struct subchannel *sch); | 113 | void css_update_ssd_info(struct subchannel *sch); |
| 114 | 114 | ||
| 115 | #define __MAX_SUBCHANNEL 65535 | ||
| 116 | #define __MAX_SSID 3 | ||
| 117 | |||
| 118 | struct channel_subsystem { | 115 | struct channel_subsystem { |
| 119 | u8 cssid; | 116 | u8 cssid; |
| 120 | int valid; | 117 | int valid; |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index fc916f5d7314..fd3143c291c6 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
| @@ -1424,7 +1424,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch) | |||
| 1424 | } | 1424 | } |
| 1425 | if (device_is_disconnected(cdev)) | 1425 | if (device_is_disconnected(cdev)) |
| 1426 | return IO_SCH_REPROBE; | 1426 | return IO_SCH_REPROBE; |
| 1427 | if (cdev->online) | 1427 | if (cdev->online && !cdev->private->flags.resuming) |
| 1428 | return IO_SCH_VERIFY; | 1428 | return IO_SCH_VERIFY; |
| 1429 | if (cdev->private->state == DEV_STATE_NOT_OPER) | 1429 | if (cdev->private->state == DEV_STATE_NOT_OPER) |
| 1430 | return IO_SCH_UNREG_ATTACH; | 1430 | return IO_SCH_UNREG_ATTACH; |
| @@ -1469,12 +1469,6 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) | |||
| 1469 | rc = 0; | 1469 | rc = 0; |
| 1470 | goto out_unlock; | 1470 | goto out_unlock; |
| 1471 | case IO_SCH_VERIFY: | 1471 | case IO_SCH_VERIFY: |
| 1472 | if (cdev->private->flags.resuming == 1) { | ||
| 1473 | if (cio_enable_subchannel(sch, (u32)(addr_t)sch)) { | ||
| 1474 | ccw_device_set_notoper(cdev); | ||
| 1475 | break; | ||
| 1476 | } | ||
| 1477 | } | ||
| 1478 | /* Trigger path verification. */ | 1472 | /* Trigger path verification. */ |
| 1479 | io_subchannel_verify(sch); | 1473 | io_subchannel_verify(sch); |
| 1480 | rc = 0; | 1474 | rc = 0; |
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c index 199bc6791177..65d13e38803f 100644 --- a/drivers/s390/cio/idset.c +++ b/drivers/s390/cio/idset.c | |||
| @@ -125,8 +125,7 @@ int idset_is_empty(struct idset *set) | |||
| 125 | 125 | ||
| 126 | void idset_add_set(struct idset *to, struct idset *from) | 126 | void idset_add_set(struct idset *to, struct idset *from) |
| 127 | { | 127 | { |
| 128 | int len = min(__BITOPS_WORDS(to->num_ssid * to->num_id), | 128 | int len = min(to->num_ssid * to->num_id, from->num_ssid * from->num_id); |
| 129 | __BITOPS_WORDS(from->num_ssid * from->num_id)); | ||
| 130 | 129 | ||
| 131 | bitmap_or(to->bitmap, to->bitmap, from->bitmap, len); | 130 | bitmap_or(to->bitmap, to->bitmap, from->bitmap, len); |
| 132 | } | 131 | } |
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index b191dd549207..71fddbc60f18 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c | |||
| @@ -1294,26 +1294,19 @@ static struct scsi_host_template qpti_template = { | |||
| 1294 | static const struct of_device_id qpti_match[]; | 1294 | static const struct of_device_id qpti_match[]; |
| 1295 | static int __devinit qpti_sbus_probe(struct platform_device *op) | 1295 | static int __devinit qpti_sbus_probe(struct platform_device *op) |
| 1296 | { | 1296 | { |
| 1297 | const struct of_device_id *match; | ||
| 1298 | struct scsi_host_template *tpnt; | ||
| 1299 | struct device_node *dp = op->dev.of_node; | 1297 | struct device_node *dp = op->dev.of_node; |
| 1300 | struct Scsi_Host *host; | 1298 | struct Scsi_Host *host; |
| 1301 | struct qlogicpti *qpti; | 1299 | struct qlogicpti *qpti; |
| 1302 | static int nqptis; | 1300 | static int nqptis; |
| 1303 | const char *fcode; | 1301 | const char *fcode; |
| 1304 | 1302 | ||
| 1305 | match = of_match_device(qpti_match, &op->dev); | ||
| 1306 | if (!match) | ||
| 1307 | return -EINVAL; | ||
| 1308 | tpnt = match->data; | ||
| 1309 | |||
| 1310 | /* Sometimes Antares cards come up not completely | 1303 | /* Sometimes Antares cards come up not completely |
| 1311 | * setup, and we get a report of a zero IRQ. | 1304 | * setup, and we get a report of a zero IRQ. |
| 1312 | */ | 1305 | */ |
| 1313 | if (op->archdata.irqs[0] == 0) | 1306 | if (op->archdata.irqs[0] == 0) |
| 1314 | return -ENODEV; | 1307 | return -ENODEV; |
| 1315 | 1308 | ||
| 1316 | host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti)); | 1309 | host = scsi_host_alloc(&qpti_template, sizeof(struct qlogicpti)); |
| 1317 | if (!host) | 1310 | if (!host) |
| 1318 | return -ENOMEM; | 1311 | return -ENOMEM; |
| 1319 | 1312 | ||
| @@ -1445,19 +1438,15 @@ static int __devexit qpti_sbus_remove(struct platform_device *op) | |||
| 1445 | static const struct of_device_id qpti_match[] = { | 1438 | static const struct of_device_id qpti_match[] = { |
| 1446 | { | 1439 | { |
| 1447 | .name = "ptisp", | 1440 | .name = "ptisp", |
| 1448 | .data = &qpti_template, | ||
| 1449 | }, | 1441 | }, |
| 1450 | { | 1442 | { |
| 1451 | .name = "PTI,ptisp", | 1443 | .name = "PTI,ptisp", |
| 1452 | .data = &qpti_template, | ||
| 1453 | }, | 1444 | }, |
| 1454 | { | 1445 | { |
| 1455 | .name = "QLGC,isp", | 1446 | .name = "QLGC,isp", |
| 1456 | .data = &qpti_template, | ||
| 1457 | }, | 1447 | }, |
| 1458 | { | 1448 | { |
| 1459 | .name = "SUNW,isp", | 1449 | .name = "SUNW,isp", |
| 1460 | .data = &qpti_template, | ||
| 1461 | }, | 1450 | }, |
| 1462 | {}, | 1451 | {}, |
| 1463 | }; | 1452 | }; |
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index f2ffd963f1c3..d0cafd637199 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h | |||
| @@ -51,12 +51,10 @@ enum android_alarm_return_flags { | |||
| 51 | #define ANDROID_ALARM_WAIT _IO('a', 1) | 51 | #define ANDROID_ALARM_WAIT _IO('a', 1) |
| 52 | 52 | ||
| 53 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) | 53 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) |
| 54 | #define ALARM_IOR(c, type, size) _IOR('a', (c) | ((type) << 4), size) | ||
| 55 | |||
| 56 | /* Set alarm */ | 54 | /* Set alarm */ |
| 57 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) | 55 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) |
| 58 | #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) | 56 | #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) |
| 59 | #define ANDROID_ALARM_GET_TIME(type) ALARM_IOR(4, type, struct timespec) | 57 | #define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) |
| 60 | #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) | 58 | #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) |
| 61 | #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) | 59 | #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) |
| 62 | #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) | 60 | #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) |
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index a5dec1ca1b82..13ee53bd0bf6 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c | |||
| @@ -424,7 +424,6 @@ static void hvc_hangup(struct tty_struct *tty) | |||
| 424 | { | 424 | { |
| 425 | struct hvc_struct *hp = tty->driver_data; | 425 | struct hvc_struct *hp = tty->driver_data; |
| 426 | unsigned long flags; | 426 | unsigned long flags; |
| 427 | int temp_open_count; | ||
| 428 | 427 | ||
| 429 | if (!hp) | 428 | if (!hp) |
| 430 | return; | 429 | return; |
| @@ -444,7 +443,6 @@ static void hvc_hangup(struct tty_struct *tty) | |||
| 444 | return; | 443 | return; |
| 445 | } | 444 | } |
| 446 | 445 | ||
| 447 | temp_open_count = hp->port.count; | ||
| 448 | hp->port.count = 0; | 446 | hp->port.count = 0; |
| 449 | spin_unlock_irqrestore(&hp->port.lock, flags); | 447 | spin_unlock_irqrestore(&hp->port.lock, flags); |
| 450 | tty_port_tty_set(&hp->port, NULL); | 448 | tty_port_tty_set(&hp->port, NULL); |
| @@ -453,11 +451,6 @@ static void hvc_hangup(struct tty_struct *tty) | |||
| 453 | 451 | ||
| 454 | if (hp->ops->notifier_hangup) | 452 | if (hp->ops->notifier_hangup) |
| 455 | hp->ops->notifier_hangup(hp, hp->data); | 453 | hp->ops->notifier_hangup(hp, hp->data); |
| 456 | |||
| 457 | while(temp_open_count) { | ||
| 458 | --temp_open_count; | ||
| 459 | tty_port_put(&hp->port); | ||
| 460 | } | ||
| 461 | } | 454 | } |
| 462 | 455 | ||
| 463 | /* | 456 | /* |
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 2bc28a59d385..1ab1d2c66de4 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
| @@ -1239,6 +1239,7 @@ static int __devexit max310x_remove(struct spi_device *spi) | |||
| 1239 | static const struct spi_device_id max310x_id_table[] = { | 1239 | static const struct spi_device_id max310x_id_table[] = { |
| 1240 | { "max3107", MAX310X_TYPE_MAX3107 }, | 1240 | { "max3107", MAX310X_TYPE_MAX3107 }, |
| 1241 | { "max3108", MAX310X_TYPE_MAX3108 }, | 1241 | { "max3108", MAX310X_TYPE_MAX3108 }, |
| 1242 | { } | ||
| 1242 | }; | 1243 | }; |
| 1243 | MODULE_DEVICE_TABLE(spi, max310x_id_table); | 1244 | MODULE_DEVICE_TABLE(spi, max310x_id_table); |
| 1244 | 1245 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 1e741bca0265..f034716190ff 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
| @@ -2151,8 +2151,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); | |||
| 2151 | irqreturn_t usb_hcd_irq (int irq, void *__hcd) | 2151 | irqreturn_t usb_hcd_irq (int irq, void *__hcd) |
| 2152 | { | 2152 | { |
| 2153 | struct usb_hcd *hcd = __hcd; | 2153 | struct usb_hcd *hcd = __hcd; |
| 2154 | unsigned long flags; | ||
| 2154 | irqreturn_t rc; | 2155 | irqreturn_t rc; |
| 2155 | 2156 | ||
| 2157 | /* IRQF_DISABLED doesn't work correctly with shared IRQs | ||
| 2158 | * when the first handler doesn't use it. So let's just | ||
| 2159 | * assume it's never used. | ||
| 2160 | */ | ||
| 2161 | local_irq_save(flags); | ||
| 2162 | |||
| 2156 | if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) | 2163 | if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) |
| 2157 | rc = IRQ_NONE; | 2164 | rc = IRQ_NONE; |
| 2158 | else if (hcd->driver->irq(hcd) == IRQ_NONE) | 2165 | else if (hcd->driver->irq(hcd) == IRQ_NONE) |
| @@ -2160,6 +2167,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) | |||
| 2160 | else | 2167 | else |
| 2161 | rc = IRQ_HANDLED; | 2168 | rc = IRQ_HANDLED; |
| 2162 | 2169 | ||
| 2170 | local_irq_restore(flags); | ||
| 2163 | return rc; | 2171 | return rc; |
| 2164 | } | 2172 | } |
| 2165 | EXPORT_SYMBOL_GPL(usb_hcd_irq); | 2173 | EXPORT_SYMBOL_GPL(usb_hcd_irq); |
| @@ -2347,6 +2355,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd, | |||
| 2347 | int retval; | 2355 | int retval; |
| 2348 | 2356 | ||
| 2349 | if (hcd->driver->irq) { | 2357 | if (hcd->driver->irq) { |
| 2358 | |||
| 2359 | /* IRQF_DISABLED doesn't work as advertised when used together | ||
| 2360 | * with IRQF_SHARED. As usb_hcd_irq() will always disable | ||
| 2361 | * interrupts we can remove it here. | ||
| 2362 | */ | ||
| 2363 | if (irqflags & IRQF_SHARED) | ||
| 2364 | irqflags &= ~IRQF_DISABLED; | ||
| 2365 | |||
| 2350 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", | 2366 | snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", |
| 2351 | hcd->driver->description, hcd->self.busnum); | 2367 | hcd->driver->description, hcd->self.busnum); |
| 2352 | retval = request_irq(irqnum, &usb_hcd_irq, irqflags, | 2368 | retval = request_irq(irqnum, &usb_hcd_irq, irqflags, |
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index e426ad626d74..4bfa78af379c 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/usb/ehci_def.h> | 20 | #include <linux/usb/ehci_def.h> |
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 22 | #include <linux/serial_core.h> | 22 | #include <linux/serial_core.h> |
| 23 | #include <linux/kconfig.h> | ||
| 23 | #include <linux/kgdb.h> | 24 | #include <linux/kgdb.h> |
| 24 | #include <linux/kthread.h> | 25 | #include <linux/kthread.h> |
| 25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
| @@ -614,12 +615,6 @@ err: | |||
| 614 | return -ENODEV; | 615 | return -ENODEV; |
| 615 | } | 616 | } |
| 616 | 617 | ||
| 617 | int dbgp_external_startup(struct usb_hcd *hcd) | ||
| 618 | { | ||
| 619 | return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); | ||
| 620 | } | ||
| 621 | EXPORT_SYMBOL_GPL(dbgp_external_startup); | ||
| 622 | |||
| 623 | static int ehci_reset_port(int port) | 618 | static int ehci_reset_port(int port) |
| 624 | { | 619 | { |
| 625 | u32 portsc; | 620 | u32 portsc; |
| @@ -979,6 +974,7 @@ struct console early_dbgp_console = { | |||
| 979 | .index = -1, | 974 | .index = -1, |
| 980 | }; | 975 | }; |
| 981 | 976 | ||
| 977 | #if IS_ENABLED(CONFIG_USB_EHCI_HCD) | ||
| 982 | int dbgp_reset_prep(struct usb_hcd *hcd) | 978 | int dbgp_reset_prep(struct usb_hcd *hcd) |
| 983 | { | 979 | { |
| 984 | int ret = xen_dbgp_reset_prep(hcd); | 980 | int ret = xen_dbgp_reset_prep(hcd); |
| @@ -1007,6 +1003,13 @@ int dbgp_reset_prep(struct usb_hcd *hcd) | |||
| 1007 | } | 1003 | } |
| 1008 | EXPORT_SYMBOL_GPL(dbgp_reset_prep); | 1004 | EXPORT_SYMBOL_GPL(dbgp_reset_prep); |
| 1009 | 1005 | ||
| 1006 | int dbgp_external_startup(struct usb_hcd *hcd) | ||
| 1007 | { | ||
| 1008 | return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); | ||
| 1009 | } | ||
| 1010 | EXPORT_SYMBOL_GPL(dbgp_external_startup); | ||
| 1011 | #endif /* USB_EHCI_HCD */ | ||
| 1012 | |||
| 1010 | #ifdef CONFIG_KGDB | 1013 | #ifdef CONFIG_KGDB |
| 1011 | 1014 | ||
| 1012 | static char kgdbdbgp_buf[DBGP_MAX_PACKET]; | 1015 | static char kgdbdbgp_buf[DBGP_MAX_PACKET]; |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 6458764994ef..4ec3c0d7a18b 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/ctype.h> | 20 | #include <linux/ctype.h> |
| 21 | #include <linux/etherdevice.h> | 21 | #include <linux/etherdevice.h> |
| 22 | #include <linux/ethtool.h> | 22 | #include <linux/ethtool.h> |
| 23 | #include <linux/if_vlan.h> | ||
| 23 | 24 | ||
| 24 | #include "u_ether.h" | 25 | #include "u_ether.h" |
| 25 | 26 | ||
| @@ -295,7 +296,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 295 | while (skb2) { | 296 | while (skb2) { |
| 296 | if (status < 0 | 297 | if (status < 0 |
| 297 | || ETH_HLEN > skb2->len | 298 | || ETH_HLEN > skb2->len |
| 298 | || skb2->len > ETH_FRAME_LEN) { | 299 | || skb2->len > VLAN_ETH_FRAME_LEN) { |
| 299 | dev->net->stats.rx_errors++; | 300 | dev->net->stats.rx_errors++; |
| 300 | dev->net->stats.rx_length_errors++; | 301 | dev->net->stats.rx_length_errors++; |
| 301 | DBG(dev, "rx length %d\n", skb2->len); | 302 | DBG(dev, "rx length %d\n", skb2->len); |
diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c index ca759652626b..aa0f328922df 100644 --- a/drivers/usb/host/ehci-ls1x.c +++ b/drivers/usb/host/ehci-ls1x.c | |||
| @@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev) | |||
| 113 | goto err_put_hcd; | 113 | goto err_put_hcd; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | ret = usb_add_hcd(hcd, irq, IRQF_SHARED); | 116 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
| 117 | if (ret) | 117 | if (ret) |
| 118 | goto err_put_hcd; | 118 | goto err_put_hcd; |
| 119 | 119 | ||
diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c index 84201cd1a472..41e378f17c66 100644 --- a/drivers/usb/host/ohci-xls.c +++ b/drivers/usb/host/ohci-xls.c | |||
| @@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver, | |||
| 56 | goto err3; | 56 | goto err3; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | 59 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
| 60 | if (retval != 0) | 60 | if (retval != 0) |
| 61 | goto err4; | 61 | goto err4; |
| 62 | return retval; | 62 | return retval; |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d0b87e7b4abf..b6b84dacc791 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
| @@ -707,11 +707,12 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
| 707 | fifo_count = musb_readw(epio, MUSB_RXCOUNT); | 707 | fifo_count = musb_readw(epio, MUSB_RXCOUNT); |
| 708 | 708 | ||
| 709 | /* | 709 | /* |
| 710 | * use mode 1 only if we expect data of at least ep packet_sz | 710 | * Enable Mode 1 on RX transfers only when short_not_ok flag |
| 711 | * and have not yet received a short packet | 711 | * is set. Currently short_not_ok flag is set only from |
| 712 | * file_storage and f_mass_storage drivers | ||
| 712 | */ | 713 | */ |
| 713 | if ((request->length - request->actual >= musb_ep->packet_sz) && | 714 | |
| 714 | (fifo_count >= musb_ep->packet_sz)) | 715 | if (request->short_not_ok && fifo_count == musb_ep->packet_sz) |
| 715 | use_mode_1 = 1; | 716 | use_mode_1 = 1; |
| 716 | else | 717 | else |
| 717 | use_mode_1 = 0; | 718 | use_mode_1 = 0; |
| @@ -727,6 +728,27 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
| 727 | c = musb->dma_controller; | 728 | c = musb->dma_controller; |
| 728 | channel = musb_ep->dma; | 729 | channel = musb_ep->dma; |
| 729 | 730 | ||
| 731 | /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in | ||
| 732 | * mode 0 only. So we do not get endpoint interrupts due to DMA | ||
| 733 | * completion. We only get interrupts from DMA controller. | ||
| 734 | * | ||
| 735 | * We could operate in DMA mode 1 if we knew the size of the tranfer | ||
| 736 | * in advance. For mass storage class, request->length = what the host | ||
| 737 | * sends, so that'd work. But for pretty much everything else, | ||
| 738 | * request->length is routinely more than what the host sends. For | ||
| 739 | * most these gadgets, end of is signified either by a short packet, | ||
| 740 | * or filling the last byte of the buffer. (Sending extra data in | ||
| 741 | * that last pckate should trigger an overflow fault.) But in mode 1, | ||
| 742 | * we don't get DMA completion interrupt for short packets. | ||
| 743 | * | ||
| 744 | * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1), | ||
| 745 | * to get endpoint interrupt on every DMA req, but that didn't seem | ||
| 746 | * to work reliably. | ||
| 747 | * | ||
| 748 | * REVISIT an updated g_file_storage can set req->short_not_ok, which | ||
| 749 | * then becomes usable as a runtime "use mode 1" hint... | ||
| 750 | */ | ||
| 751 | |||
| 730 | /* Experimental: Mode1 works with mass storage use cases */ | 752 | /* Experimental: Mode1 works with mass storage use cases */ |
| 731 | if (use_mode_1) { | 753 | if (use_mode_1) { |
| 732 | csr |= MUSB_RXCSR_AUTOCLEAR; | 754 | csr |= MUSB_RXCSR_AUTOCLEAR; |
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index d62a91fedc22..0e62f504410e 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c | |||
| @@ -65,7 +65,7 @@ static int __devinit ux500_probe(struct platform_device *pdev) | |||
| 65 | struct platform_device *musb; | 65 | struct platform_device *musb; |
| 66 | struct ux500_glue *glue; | 66 | struct ux500_glue *glue; |
| 67 | struct clk *clk; | 67 | struct clk *clk; |
| 68 | 68 | int musbid; | |
| 69 | int ret = -ENOMEM; | 69 | int ret = -ENOMEM; |
| 70 | 70 | ||
| 71 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 71 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); |
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index d8c8a42bff3e..6223062d5d1b 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig | |||
| @@ -58,7 +58,7 @@ config USB_ULPI_VIEWPORT | |||
| 58 | 58 | ||
| 59 | config TWL4030_USB | 59 | config TWL4030_USB |
| 60 | tristate "TWL4030 USB Transceiver Driver" | 60 | tristate "TWL4030 USB Transceiver Driver" |
| 61 | depends on TWL4030_CORE && REGULATOR_TWL4030 | 61 | depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS |
| 62 | select USB_OTG_UTILS | 62 | select USB_OTG_UTILS |
| 63 | help | 63 | help |
| 64 | Enable this to support the USB OTG transceiver on TWL4030 | 64 | Enable this to support the USB OTG transceiver on TWL4030 |
| @@ -68,7 +68,7 @@ config TWL4030_USB | |||
| 68 | 68 | ||
| 69 | config TWL6030_USB | 69 | config TWL6030_USB |
| 70 | tristate "TWL6030 USB Transceiver Driver" | 70 | tristate "TWL6030 USB Transceiver Driver" |
| 71 | depends on TWL4030_CORE && OMAP_USB2 | 71 | depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS |
| 72 | select USB_OTG_UTILS | 72 | select USB_OTG_UTILS |
| 73 | help | 73 | help |
| 74 | Enable this to support the USB OTG transceiver on TWL6030 | 74 | Enable this to support the USB OTG transceiver on TWL6030 |
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 7179b0c5f814..cff8dd5b462d 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
| @@ -2430,7 +2430,7 @@ static void keyspan_release(struct usb_serial *serial) | |||
| 2430 | static int keyspan_port_probe(struct usb_serial_port *port) | 2430 | static int keyspan_port_probe(struct usb_serial_port *port) |
| 2431 | { | 2431 | { |
| 2432 | struct usb_serial *serial = port->serial; | 2432 | struct usb_serial *serial = port->serial; |
| 2433 | struct keyspan_port_private *s_priv; | 2433 | struct keyspan_serial_private *s_priv; |
| 2434 | struct keyspan_port_private *p_priv; | 2434 | struct keyspan_port_private *p_priv; |
| 2435 | const struct keyspan_device_details *d_details; | 2435 | const struct keyspan_device_details *d_details; |
| 2436 | struct callbacks *cback; | 2436 | struct callbacks *cback; |
| @@ -2445,7 +2445,6 @@ static int keyspan_port_probe(struct usb_serial_port *port) | |||
| 2445 | if (!p_priv) | 2445 | if (!p_priv) |
| 2446 | return -ENOMEM; | 2446 | return -ENOMEM; |
| 2447 | 2447 | ||
| 2448 | s_priv = usb_get_serial_data(port->serial); | ||
| 2449 | p_priv->device_details = d_details; | 2448 | p_priv->device_details = d_details; |
| 2450 | 2449 | ||
| 2451 | /* Setup values for the various callback routines */ | 2450 | /* Setup values for the various callback routines */ |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5dee7d61241e..edc64bb6f457 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -158,6 +158,7 @@ static void option_instat_callback(struct urb *urb); | |||
| 158 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 | 158 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 |
| 159 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 | 159 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 |
| 160 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 | 160 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 |
| 161 | #define NOVATELWIRELESS_PRODUCT_E362 0x9010 | ||
| 161 | #define NOVATELWIRELESS_PRODUCT_G1 0xA001 | 162 | #define NOVATELWIRELESS_PRODUCT_G1 0xA001 |
| 162 | #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 | 163 | #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 |
| 163 | #define NOVATELWIRELESS_PRODUCT_G2 0xA010 | 164 | #define NOVATELWIRELESS_PRODUCT_G2 0xA010 |
| @@ -193,6 +194,9 @@ static void option_instat_callback(struct urb *urb); | |||
| 193 | #define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 | 194 | #define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 |
| 194 | #define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 | 195 | #define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 |
| 195 | 196 | ||
| 197 | #define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */ | ||
| 198 | #define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */ | ||
| 199 | |||
| 196 | #define KYOCERA_VENDOR_ID 0x0c88 | 200 | #define KYOCERA_VENDOR_ID 0x0c88 |
| 197 | #define KYOCERA_PRODUCT_KPC650 0x17da | 201 | #define KYOCERA_PRODUCT_KPC650 0x17da |
| 198 | #define KYOCERA_PRODUCT_KPC680 0x180a | 202 | #define KYOCERA_PRODUCT_KPC680 0x180a |
| @@ -283,6 +287,7 @@ static void option_instat_callback(struct urb *urb); | |||
| 283 | /* ALCATEL PRODUCTS */ | 287 | /* ALCATEL PRODUCTS */ |
| 284 | #define ALCATEL_VENDOR_ID 0x1bbb | 288 | #define ALCATEL_VENDOR_ID 0x1bbb |
| 285 | #define ALCATEL_PRODUCT_X060S_X200 0x0000 | 289 | #define ALCATEL_PRODUCT_X060S_X200 0x0000 |
| 290 | #define ALCATEL_PRODUCT_X220_X500D 0x0017 | ||
| 286 | 291 | ||
| 287 | #define PIRELLI_VENDOR_ID 0x1266 | 292 | #define PIRELLI_VENDOR_ID 0x1266 |
| 288 | #define PIRELLI_PRODUCT_C100_1 0x1002 | 293 | #define PIRELLI_PRODUCT_C100_1 0x1002 |
| @@ -706,6 +711,7 @@ static const struct usb_device_id option_ids[] = { | |||
| 706 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, | 711 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, |
| 707 | /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ | 712 | /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ |
| 708 | { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, | 713 | { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, |
| 714 | { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) }, | ||
| 709 | 715 | ||
| 710 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, | 716 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, |
| 711 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, | 717 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, |
| @@ -728,6 +734,8 @@ static const struct usb_device_id option_ids[] = { | |||
| 728 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ | 734 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ |
| 729 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ | 735 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ |
| 730 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ | 736 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ |
| 737 | { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) }, | ||
| 738 | { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) }, | ||
| 731 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ | 739 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ |
| 732 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, | 740 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
| 733 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, | 741 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, |
| @@ -1157,6 +1165,7 @@ static const struct usb_device_id option_ids[] = { | |||
| 1157 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), | 1165 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), |
| 1158 | .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist | 1166 | .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist |
| 1159 | }, | 1167 | }, |
| 1168 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) }, | ||
| 1160 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, | 1169 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, |
| 1161 | { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, | 1170 | { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, |
| 1162 | { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), | 1171 | { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 61a73ad1a187..a3e9c095f0d8 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
| @@ -455,9 +455,6 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, | |||
| 455 | struct usb_serial *serial = port->serial; | 455 | struct usb_serial *serial = port->serial; |
| 456 | struct urb *urb; | 456 | struct urb *urb; |
| 457 | 457 | ||
| 458 | if (endpoint == -1) | ||
| 459 | return NULL; /* endpoint not needed */ | ||
| 460 | |||
| 461 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ | 458 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ |
| 462 | if (urb == NULL) { | 459 | if (urb == NULL) { |
| 463 | dev_dbg(&serial->interface->dev, | 460 | dev_dbg(&serial->interface->dev, |
| @@ -489,6 +486,9 @@ int usb_wwan_port_probe(struct usb_serial_port *port) | |||
| 489 | init_usb_anchor(&portdata->delayed); | 486 | init_usb_anchor(&portdata->delayed); |
| 490 | 487 | ||
| 491 | for (i = 0; i < N_IN_URB; i++) { | 488 | for (i = 0; i < N_IN_URB; i++) { |
| 489 | if (!port->bulk_in_size) | ||
| 490 | break; | ||
| 491 | |||
| 492 | buffer = (u8 *)__get_free_page(GFP_KERNEL); | 492 | buffer = (u8 *)__get_free_page(GFP_KERNEL); |
| 493 | if (!buffer) | 493 | if (!buffer) |
| 494 | goto bail_out_error; | 494 | goto bail_out_error; |
| @@ -502,8 +502,8 @@ int usb_wwan_port_probe(struct usb_serial_port *port) | |||
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | for (i = 0; i < N_OUT_URB; i++) { | 504 | for (i = 0; i < N_OUT_URB; i++) { |
| 505 | if (port->bulk_out_endpointAddress == -1) | 505 | if (!port->bulk_out_size) |
| 506 | continue; | 506 | break; |
| 507 | 507 | ||
| 508 | buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); | 508 | buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); |
| 509 | if (!buffer) | 509 | if (!buffer) |
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 0e8637035457..74354708c6c4 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile | |||
| @@ -2,6 +2,7 @@ ifneq ($(CONFIG_ARM),y) | |||
| 2 | obj-y += manage.o balloon.o | 2 | obj-y += manage.o balloon.o |
| 3 | obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o | 3 | obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o |
| 4 | endif | 4 | endif |
| 5 | obj-$(CONFIG_X86) += fallback.o | ||
| 5 | obj-y += grant-table.o features.o events.o | 6 | obj-y += grant-table.o features.o events.o |
| 6 | obj-y += xenbus/ | 7 | obj-y += xenbus/ |
| 7 | 8 | ||
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 912ac81b6dbf..0be4df39e953 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
| @@ -1395,10 +1395,10 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) | |||
| 1395 | { | 1395 | { |
| 1396 | struct pt_regs *old_regs = set_irq_regs(regs); | 1396 | struct pt_regs *old_regs = set_irq_regs(regs); |
| 1397 | 1397 | ||
| 1398 | irq_enter(); | ||
| 1398 | #ifdef CONFIG_X86 | 1399 | #ifdef CONFIG_X86 |
| 1399 | exit_idle(); | 1400 | exit_idle(); |
| 1400 | #endif | 1401 | #endif |
| 1401 | irq_enter(); | ||
| 1402 | 1402 | ||
| 1403 | __xen_evtchn_do_upcall(); | 1403 | __xen_evtchn_do_upcall(); |
| 1404 | 1404 | ||
diff --git a/drivers/xen/fallback.c b/drivers/xen/fallback.c new file mode 100644 index 000000000000..0ef7c4d40f86 --- /dev/null +++ b/drivers/xen/fallback.c | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | #include <linux/kernel.h> | ||
| 2 | #include <linux/string.h> | ||
| 3 | #include <linux/bug.h> | ||
| 4 | #include <linux/export.h> | ||
| 5 | #include <asm/hypervisor.h> | ||
| 6 | #include <asm/xen/hypercall.h> | ||
| 7 | |||
| 8 | int xen_event_channel_op_compat(int cmd, void *arg) | ||
| 9 | { | ||
| 10 | struct evtchn_op op; | ||
| 11 | int rc; | ||
| 12 | |||
| 13 | op.cmd = cmd; | ||
| 14 | memcpy(&op.u, arg, sizeof(op.u)); | ||
| 15 | rc = _hypercall1(int, event_channel_op_compat, &op); | ||
| 16 | |||
| 17 | switch (cmd) { | ||
| 18 | case EVTCHNOP_close: | ||
| 19 | case EVTCHNOP_send: | ||
| 20 | case EVTCHNOP_bind_vcpu: | ||
| 21 | case EVTCHNOP_unmask: | ||
| 22 | /* no output */ | ||
| 23 | break; | ||
| 24 | |||
| 25 | #define COPY_BACK(eop) \ | ||
| 26 | case EVTCHNOP_##eop: \ | ||
| 27 | memcpy(arg, &op.u.eop, sizeof(op.u.eop)); \ | ||
| 28 | break | ||
| 29 | |||
| 30 | COPY_BACK(bind_interdomain); | ||
| 31 | COPY_BACK(bind_virq); | ||
| 32 | COPY_BACK(bind_pirq); | ||
| 33 | COPY_BACK(status); | ||
| 34 | COPY_BACK(alloc_unbound); | ||
| 35 | COPY_BACK(bind_ipi); | ||
| 36 | #undef COPY_BACK | ||
| 37 | |||
| 38 | default: | ||
| 39 | WARN_ON(rc != -ENOSYS); | ||
| 40 | break; | ||
| 41 | } | ||
| 42 | |||
| 43 | return rc; | ||
| 44 | } | ||
| 45 | EXPORT_SYMBOL_GPL(xen_event_channel_op_compat); | ||
| 46 | |||
| 47 | int HYPERVISOR_physdev_op_compat(int cmd, void *arg) | ||
| 48 | { | ||
| 49 | struct physdev_op op; | ||
| 50 | int rc; | ||
| 51 | |||
| 52 | op.cmd = cmd; | ||
| 53 | memcpy(&op.u, arg, sizeof(op.u)); | ||
| 54 | rc = _hypercall1(int, physdev_op_compat, &op); | ||
| 55 | |||
| 56 | switch (cmd) { | ||
| 57 | case PHYSDEVOP_IRQ_UNMASK_NOTIFY: | ||
| 58 | case PHYSDEVOP_set_iopl: | ||
| 59 | case PHYSDEVOP_set_iobitmap: | ||
| 60 | case PHYSDEVOP_apic_write: | ||
| 61 | /* no output */ | ||
| 62 | break; | ||
| 63 | |||
| 64 | #define COPY_BACK(pop, fld) \ | ||
| 65 | case PHYSDEVOP_##pop: \ | ||
| 66 | memcpy(arg, &op.u.fld, sizeof(op.u.fld)); \ | ||
| 67 | break | ||
| 68 | |||
| 69 | COPY_BACK(irq_status_query, irq_status_query); | ||
| 70 | COPY_BACK(apic_read, apic_op); | ||
| 71 | COPY_BACK(ASSIGN_VECTOR, irq_op); | ||
| 72 | #undef COPY_BACK | ||
| 73 | |||
| 74 | default: | ||
| 75 | WARN_ON(rc != -ENOSYS); | ||
| 76 | break; | ||
| 77 | } | ||
| 78 | |||
| 79 | return rc; | ||
| 80 | } | ||
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index fc783e264420..0fb15bbbe43c 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
| @@ -225,6 +225,13 @@ sid_to_str(struct cifs_sid *sidptr, char *sidstr) | |||
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | static void | 227 | static void |
| 228 | cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src) | ||
| 229 | { | ||
| 230 | memcpy(dst, src, sizeof(*dst)); | ||
| 231 | dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS); | ||
| 232 | } | ||
| 233 | |||
| 234 | static void | ||
| 228 | id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, | 235 | id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, |
| 229 | struct cifs_sid_id **psidid, char *typestr) | 236 | struct cifs_sid_id **psidid, char *typestr) |
| 230 | { | 237 | { |
| @@ -248,7 +255,7 @@ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, | |||
| 248 | } | 255 | } |
| 249 | } | 256 | } |
| 250 | 257 | ||
| 251 | memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid)); | 258 | cifs_copy_sid(&(*psidid)->sid, sidptr); |
| 252 | (*psidid)->time = jiffies - (SID_MAP_RETRY + 1); | 259 | (*psidid)->time = jiffies - (SID_MAP_RETRY + 1); |
| 253 | (*psidid)->refcount = 0; | 260 | (*psidid)->refcount = 0; |
| 254 | 261 | ||
| @@ -354,7 +361,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) | |||
| 354 | * any fields of the node after a reference is put . | 361 | * any fields of the node after a reference is put . |
| 355 | */ | 362 | */ |
| 356 | if (test_bit(SID_ID_MAPPED, &psidid->state)) { | 363 | if (test_bit(SID_ID_MAPPED, &psidid->state)) { |
| 357 | memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); | 364 | cifs_copy_sid(ssid, &psidid->sid); |
| 358 | psidid->time = jiffies; /* update ts for accessing */ | 365 | psidid->time = jiffies; /* update ts for accessing */ |
| 359 | goto id_sid_out; | 366 | goto id_sid_out; |
| 360 | } | 367 | } |
| @@ -370,14 +377,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) | |||
| 370 | if (IS_ERR(sidkey)) { | 377 | if (IS_ERR(sidkey)) { |
| 371 | rc = -EINVAL; | 378 | rc = -EINVAL; |
| 372 | cFYI(1, "%s: Can't map and id to a SID", __func__); | 379 | cFYI(1, "%s: Can't map and id to a SID", __func__); |
| 380 | } else if (sidkey->datalen < sizeof(struct cifs_sid)) { | ||
| 381 | rc = -EIO; | ||
| 382 | cFYI(1, "%s: Downcall contained malformed key " | ||
| 383 | "(datalen=%hu)", __func__, sidkey->datalen); | ||
| 373 | } else { | 384 | } else { |
| 374 | lsid = (struct cifs_sid *)sidkey->payload.data; | 385 | lsid = (struct cifs_sid *)sidkey->payload.data; |
| 375 | memcpy(&psidid->sid, lsid, | 386 | cifs_copy_sid(&psidid->sid, lsid); |
| 376 | sidkey->datalen < sizeof(struct cifs_sid) ? | 387 | cifs_copy_sid(ssid, &psidid->sid); |
| 377 | sidkey->datalen : sizeof(struct cifs_sid)); | ||
| 378 | memcpy(ssid, &psidid->sid, | ||
| 379 | sidkey->datalen < sizeof(struct cifs_sid) ? | ||
| 380 | sidkey->datalen : sizeof(struct cifs_sid)); | ||
| 381 | set_bit(SID_ID_MAPPED, &psidid->state); | 388 | set_bit(SID_ID_MAPPED, &psidid->state); |
| 382 | key_put(sidkey); | 389 | key_put(sidkey); |
| 383 | kfree(psidid->sidstr); | 390 | kfree(psidid->sidstr); |
| @@ -396,7 +403,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) | |||
| 396 | return rc; | 403 | return rc; |
| 397 | } | 404 | } |
| 398 | if (test_bit(SID_ID_MAPPED, &psidid->state)) | 405 | if (test_bit(SID_ID_MAPPED, &psidid->state)) |
| 399 | memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); | 406 | cifs_copy_sid(ssid, &psidid->sid); |
| 400 | else | 407 | else |
| 401 | rc = -EINVAL; | 408 | rc = -EINVAL; |
| 402 | } | 409 | } |
| @@ -675,8 +682,6 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) | |||
| 675 | static void copy_sec_desc(const struct cifs_ntsd *pntsd, | 682 | static void copy_sec_desc(const struct cifs_ntsd *pntsd, |
| 676 | struct cifs_ntsd *pnntsd, __u32 sidsoffset) | 683 | struct cifs_ntsd *pnntsd, __u32 sidsoffset) |
| 677 | { | 684 | { |
| 678 | int i; | ||
| 679 | |||
| 680 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; | 685 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; |
| 681 | struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; | 686 | struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; |
| 682 | 687 | ||
| @@ -692,26 +697,14 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd, | |||
| 692 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + | 697 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + |
| 693 | le32_to_cpu(pntsd->osidoffset)); | 698 | le32_to_cpu(pntsd->osidoffset)); |
| 694 | nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); | 699 | nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); |
| 695 | 700 | cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr); | |
| 696 | nowner_sid_ptr->revision = owner_sid_ptr->revision; | ||
| 697 | nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth; | ||
| 698 | for (i = 0; i < 6; i++) | ||
| 699 | nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i]; | ||
| 700 | for (i = 0; i < 5; i++) | ||
| 701 | nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i]; | ||
| 702 | 701 | ||
| 703 | /* copy group sid */ | 702 | /* copy group sid */ |
| 704 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + | 703 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + |
| 705 | le32_to_cpu(pntsd->gsidoffset)); | 704 | le32_to_cpu(pntsd->gsidoffset)); |
| 706 | ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + | 705 | ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + |
| 707 | sizeof(struct cifs_sid)); | 706 | sizeof(struct cifs_sid)); |
| 708 | 707 | cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr); | |
| 709 | ngroup_sid_ptr->revision = group_sid_ptr->revision; | ||
| 710 | ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth; | ||
| 711 | for (i = 0; i < 6; i++) | ||
| 712 | ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i]; | ||
| 713 | for (i = 0; i < 5; i++) | ||
| 714 | ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i]; | ||
| 715 | 708 | ||
| 716 | return; | 709 | return; |
| 717 | } | 710 | } |
| @@ -1120,8 +1113,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
| 1120 | kfree(nowner_sid_ptr); | 1113 | kfree(nowner_sid_ptr); |
| 1121 | return rc; | 1114 | return rc; |
| 1122 | } | 1115 | } |
| 1123 | memcpy(owner_sid_ptr, nowner_sid_ptr, | 1116 | cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr); |
| 1124 | sizeof(struct cifs_sid)); | ||
| 1125 | kfree(nowner_sid_ptr); | 1117 | kfree(nowner_sid_ptr); |
| 1126 | *aclflag = CIFS_ACL_OWNER; | 1118 | *aclflag = CIFS_ACL_OWNER; |
| 1127 | } | 1119 | } |
| @@ -1139,8 +1131,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
| 1139 | kfree(ngroup_sid_ptr); | 1131 | kfree(ngroup_sid_ptr); |
| 1140 | return rc; | 1132 | return rc; |
| 1141 | } | 1133 | } |
| 1142 | memcpy(group_sid_ptr, ngroup_sid_ptr, | 1134 | cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr); |
| 1143 | sizeof(struct cifs_sid)); | ||
| 1144 | kfree(ngroup_sid_ptr); | 1135 | kfree(ngroup_sid_ptr); |
| 1145 | *aclflag = CIFS_ACL_GROUP; | 1136 | *aclflag = CIFS_ACL_GROUP; |
| 1146 | } | 1137 | } |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 7c0a81283645..d3671f2acb29 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
| @@ -398,7 +398,16 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, | |||
| 398 | * in network traffic in the other paths. | 398 | * in network traffic in the other paths. |
| 399 | */ | 399 | */ |
| 400 | if (!(oflags & O_CREAT)) { | 400 | if (!(oflags & O_CREAT)) { |
| 401 | struct dentry *res = cifs_lookup(inode, direntry, 0); | 401 | struct dentry *res; |
| 402 | |||
| 403 | /* | ||
| 404 | * Check for hashed negative dentry. We have already revalidated | ||
| 405 | * the dentry and it is fine. No need to perform another lookup. | ||
| 406 | */ | ||
| 407 | if (!d_unhashed(direntry)) | ||
| 408 | return -ENOENT; | ||
| 409 | |||
| 410 | res = cifs_lookup(inode, direntry, 0); | ||
| 402 | if (IS_ERR(res)) | 411 | if (IS_ERR(res)) |
| 403 | return PTR_ERR(res); | 412 | return PTR_ERR(res); |
| 404 | 413 | ||
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index a40da07e93d6..947fbe06c3b1 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c | |||
| @@ -161,6 +161,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) | |||
| 161 | 161 | ||
| 162 | while (s < e) { | 162 | while (s < e) { |
| 163 | unsigned long flags; | 163 | unsigned long flags; |
| 164 | u64 id; | ||
| 164 | 165 | ||
| 165 | if (c > psinfo->bufsize) | 166 | if (c > psinfo->bufsize) |
| 166 | c = psinfo->bufsize; | 167 | c = psinfo->bufsize; |
| @@ -172,7 +173,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) | |||
| 172 | spin_lock_irqsave(&psinfo->buf_lock, flags); | 173 | spin_lock_irqsave(&psinfo->buf_lock, flags); |
| 173 | } | 174 | } |
| 174 | memcpy(psinfo->buf, s, c); | 175 | memcpy(psinfo->buf, s, c); |
| 175 | psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo); | 176 | psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo); |
| 176 | spin_unlock_irqrestore(&psinfo->buf_lock, flags); | 177 | spin_unlock_irqrestore(&psinfo->buf_lock, flags); |
| 177 | s += c; | 178 | s += c; |
| 178 | c = e - s; | 179 | c = e - s; |
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c index 28ec13af28d9..2dcf3d473fec 100644 --- a/fs/ubifs/find.c +++ b/fs/ubifs/find.c | |||
| @@ -681,8 +681,16 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c) | |||
| 681 | if (!lprops) { | 681 | if (!lprops) { |
| 682 | lprops = ubifs_fast_find_freeable(c); | 682 | lprops = ubifs_fast_find_freeable(c); |
| 683 | if (!lprops) { | 683 | if (!lprops) { |
| 684 | ubifs_assert(c->freeable_cnt == 0); | 684 | /* |
| 685 | if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { | 685 | * The first condition means the following: go scan the |
| 686 | * LPT if there are uncategorized lprops, which means | ||
| 687 | * there may be freeable LEBs there (UBIFS does not | ||
| 688 | * store the information about freeable LEBs in the | ||
| 689 | * master node). | ||
| 690 | */ | ||
| 691 | if (c->in_a_category_cnt != c->main_lebs || | ||
| 692 | c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { | ||
| 693 | ubifs_assert(c->freeable_cnt == 0); | ||
| 686 | lprops = scan_for_leb_for_idx(c); | 694 | lprops = scan_for_leb_for_idx(c); |
| 687 | if (IS_ERR(lprops)) { | 695 | if (IS_ERR(lprops)) { |
| 688 | err = PTR_ERR(lprops); | 696 | err = PTR_ERR(lprops); |
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c index e5a2a35a46dc..46190a7c42a6 100644 --- a/fs/ubifs/lprops.c +++ b/fs/ubifs/lprops.c | |||
| @@ -300,8 +300,11 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops, | |||
| 300 | default: | 300 | default: |
| 301 | ubifs_assert(0); | 301 | ubifs_assert(0); |
| 302 | } | 302 | } |
| 303 | |||
| 303 | lprops->flags &= ~LPROPS_CAT_MASK; | 304 | lprops->flags &= ~LPROPS_CAT_MASK; |
| 304 | lprops->flags |= cat; | 305 | lprops->flags |= cat; |
| 306 | c->in_a_category_cnt += 1; | ||
| 307 | ubifs_assert(c->in_a_category_cnt <= c->main_lebs); | ||
| 305 | } | 308 | } |
| 306 | 309 | ||
| 307 | /** | 310 | /** |
| @@ -334,6 +337,9 @@ static void ubifs_remove_from_cat(struct ubifs_info *c, | |||
| 334 | default: | 337 | default: |
| 335 | ubifs_assert(0); | 338 | ubifs_assert(0); |
| 336 | } | 339 | } |
| 340 | |||
| 341 | c->in_a_category_cnt -= 1; | ||
| 342 | ubifs_assert(c->in_a_category_cnt >= 0); | ||
| 337 | } | 343 | } |
| 338 | 344 | ||
| 339 | /** | 345 | /** |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 5486346d0a3f..d133c276fe05 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
| @@ -1183,6 +1183,8 @@ struct ubifs_debug_info; | |||
| 1183 | * @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size) | 1183 | * @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size) |
| 1184 | * @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size) | 1184 | * @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size) |
| 1185 | * @freeable_cnt: number of freeable LEBs in @freeable_list | 1185 | * @freeable_cnt: number of freeable LEBs in @freeable_list |
| 1186 | * @in_a_category_cnt: count of lprops which are in a certain category, which | ||
| 1187 | * basically meants that they were loaded from the flash | ||
| 1186 | * | 1188 | * |
| 1187 | * @ltab_lnum: LEB number of LPT's own lprops table | 1189 | * @ltab_lnum: LEB number of LPT's own lprops table |
| 1188 | * @ltab_offs: offset of LPT's own lprops table | 1190 | * @ltab_offs: offset of LPT's own lprops table |
| @@ -1412,6 +1414,7 @@ struct ubifs_info { | |||
| 1412 | struct list_head freeable_list; | 1414 | struct list_head freeable_list; |
| 1413 | struct list_head frdi_idx_list; | 1415 | struct list_head frdi_idx_list; |
| 1414 | int freeable_cnt; | 1416 | int freeable_cnt; |
| 1417 | int in_a_category_cnt; | ||
| 1415 | 1418 | ||
| 1416 | int ltab_lnum; | 1419 | int ltab_lnum; |
| 1417 | int ltab_offs; | 1420 | int ltab_offs; |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c12731582920..f9f5e9eeb9dd 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
| @@ -335,8 +335,8 @@ const char *__clk_get_name(struct clk *clk); | |||
| 335 | struct clk_hw *__clk_get_hw(struct clk *clk); | 335 | struct clk_hw *__clk_get_hw(struct clk *clk); |
| 336 | u8 __clk_get_num_parents(struct clk *clk); | 336 | u8 __clk_get_num_parents(struct clk *clk); |
| 337 | struct clk *__clk_get_parent(struct clk *clk); | 337 | struct clk *__clk_get_parent(struct clk *clk); |
| 338 | inline int __clk_get_enable_count(struct clk *clk); | 338 | int __clk_get_enable_count(struct clk *clk); |
| 339 | inline int __clk_get_prepare_count(struct clk *clk); | 339 | int __clk_get_prepare_count(struct clk *clk); |
| 340 | unsigned long __clk_get_rate(struct clk *clk); | 340 | unsigned long __clk_get_rate(struct clk *clk); |
| 341 | unsigned long __clk_get_flags(struct clk *clk); | 341 | unsigned long __clk_get_flags(struct clk *clk); |
| 342 | int __clk_is_enabled(struct clk *clk); | 342 | int __clk_is_enabled(struct clk *clk); |
diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h index ca8d7e94eb3c..55f277372fed 100644 --- a/include/linux/hid-sensor-ids.h +++ b/include/linux/hid-sensor-ids.h | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #ifndef _HID_SENSORS_IDS_H | 19 | #ifndef _HID_SENSORS_IDS_H |
| 20 | #define _HID_SENSORS_IDS_H | 20 | #define _HID_SENSORS_IDS_H |
| 21 | 21 | ||
| 22 | #define HID_UP_SENSOR 0x00200000 | ||
| 23 | #define HID_MAX_PHY_DEVICES 0xFF | 22 | #define HID_MAX_PHY_DEVICES 0xFF |
| 24 | 23 | ||
| 25 | /* Accel 3D (200073) */ | 24 | /* Accel 3D (200073) */ |
diff --git a/include/linux/hid.h b/include/linux/hid.h index d2c42dd222c1..7330a0fef0c0 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
| @@ -167,6 +167,7 @@ struct hid_item { | |||
| 167 | #define HID_UP_MSVENDOR 0xff000000 | 167 | #define HID_UP_MSVENDOR 0xff000000 |
| 168 | #define HID_UP_CUSTOM 0x00ff0000 | 168 | #define HID_UP_CUSTOM 0x00ff0000 |
| 169 | #define HID_UP_LOGIVENDOR 0xffbc0000 | 169 | #define HID_UP_LOGIVENDOR 0xffbc0000 |
| 170 | #define HID_UP_SENSOR 0x00200000 | ||
| 170 | 171 | ||
| 171 | #define HID_USAGE 0x0000ffff | 172 | #define HID_USAGE 0x0000ffff |
| 172 | 173 | ||
| @@ -292,6 +293,7 @@ struct hid_item { | |||
| 292 | */ | 293 | */ |
| 293 | #define HID_GROUP_GENERIC 0x0001 | 294 | #define HID_GROUP_GENERIC 0x0001 |
| 294 | #define HID_GROUP_MULTITOUCH 0x0002 | 295 | #define HID_GROUP_MULTITOUCH 0x0002 |
| 296 | #define HID_GROUP_SENSOR_HUB 0x0003 | ||
| 295 | 297 | ||
| 296 | /* | 298 | /* |
| 297 | * This is the global environment of the parser. This information is | 299 | * This is the global environment of the parser. This information is |
| @@ -685,6 +687,7 @@ struct hid_ll_driver { | |||
| 685 | 687 | ||
| 686 | extern int hid_debug; | 688 | extern int hid_debug; |
| 687 | 689 | ||
| 690 | extern bool hid_ignore(struct hid_device *); | ||
| 688 | extern int hid_add_device(struct hid_device *); | 691 | extern int hid_add_device(struct hid_device *); |
| 689 | extern void hid_destroy_device(struct hid_device *); | 692 | extern void hid_destroy_device(struct hid_device *); |
| 690 | 693 | ||
diff --git a/include/linux/i2c/i2c-hid.h b/include/linux/i2c/i2c-hid.h new file mode 100644 index 000000000000..60e411d764d4 --- /dev/null +++ b/include/linux/i2c/i2c-hid.h | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | /* | ||
| 2 | * HID over I2C protocol implementation | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> | ||
| 5 | * Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France | ||
| 6 | * | ||
| 7 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 8 | * License. See the file COPYING in the main directory of this archive for | ||
| 9 | * more details. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __LINUX_I2C_HID_H | ||
| 13 | #define __LINUX_I2C_HID_H | ||
| 14 | |||
| 15 | #include <linux/types.h> | ||
| 16 | |||
| 17 | /** | ||
| 18 | * struct i2chid_platform_data - used by hid over i2c implementation. | ||
| 19 | * @hid_descriptor_address: i2c register where the HID descriptor is stored. | ||
| 20 | * | ||
| 21 | * Note that it is the responsibility of the platform driver (or the acpi 5.0 | ||
| 22 | * driver) to setup the irq related to the gpio in the struct i2c_board_info. | ||
| 23 | * The platform driver should also setup the gpio according to the device: | ||
| 24 | * | ||
| 25 | * A typical example is the following: | ||
| 26 | * irq = gpio_to_irq(intr_gpio); | ||
| 27 | * hkdk4412_i2c_devs5[0].irq = irq; // store the irq in i2c_board_info | ||
| 28 | * gpio_request(intr_gpio, "elan-irq"); | ||
| 29 | * s3c_gpio_setpull(intr_gpio, S3C_GPIO_PULL_UP); | ||
| 30 | */ | ||
| 31 | struct i2c_hid_platform_data { | ||
| 32 | u16 hid_descriptor_address; | ||
| 33 | }; | ||
| 34 | |||
| 35 | #endif /* __LINUX_I2C_HID_H */ | ||
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index 7c6a1139d8fa..96531664a061 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h | |||
| @@ -137,7 +137,7 @@ struct dw_mci { | |||
| 137 | 137 | ||
| 138 | dma_addr_t sg_dma; | 138 | dma_addr_t sg_dma; |
| 139 | void *sg_cpu; | 139 | void *sg_cpu; |
| 140 | struct dw_mci_dma_ops *dma_ops; | 140 | const struct dw_mci_dma_ops *dma_ops; |
| 141 | #ifdef CONFIG_MMC_DW_IDMAC | 141 | #ifdef CONFIG_MMC_DW_IDMAC |
| 142 | unsigned int ring_size; | 142 | unsigned int ring_size; |
| 143 | #else | 143 | #else |
| @@ -162,7 +162,7 @@ struct dw_mci { | |||
| 162 | u16 data_offset; | 162 | u16 data_offset; |
| 163 | struct device *dev; | 163 | struct device *dev; |
| 164 | struct dw_mci_board *pdata; | 164 | struct dw_mci_board *pdata; |
| 165 | struct dw_mci_drv_data *drv_data; | 165 | const struct dw_mci_drv_data *drv_data; |
| 166 | void *priv; | 166 | void *priv; |
| 167 | struct clk *biu_clk; | 167 | struct clk *biu_clk; |
| 168 | struct clk *ciu_clk; | 168 | struct clk *ciu_clk; |
| @@ -186,7 +186,7 @@ struct dw_mci { | |||
| 186 | 186 | ||
| 187 | struct regulator *vmmc; /* Power regulator */ | 187 | struct regulator *vmmc; /* Power regulator */ |
| 188 | unsigned long irq_flags; /* IRQ flags */ | 188 | unsigned long irq_flags; /* IRQ flags */ |
| 189 | unsigned int irq; | 189 | int irq; |
| 190 | }; | 190 | }; |
| 191 | 191 | ||
| 192 | /* DMA ops for Internal/External DMAC interface */ | 192 | /* DMA ops for Internal/External DMAC interface */ |
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index fa8529a859b8..1edcb4dad8c4 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h | |||
| @@ -91,6 +91,7 @@ struct sdhci_host { | |||
| 91 | unsigned int quirks2; /* More deviations from spec. */ | 91 | unsigned int quirks2; /* More deviations from spec. */ |
| 92 | 92 | ||
| 93 | #define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0) | 93 | #define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0) |
| 94 | #define SDHCI_QUIRK2_HOST_NO_CMD23 (1<<1) | ||
| 94 | 95 | ||
| 95 | int irq; /* Device IRQ */ | 96 | int irq; /* Device IRQ */ |
| 96 | void __iomem *ioaddr; /* Mapped address */ | 97 | void __iomem *ioaddr; /* Mapped address */ |
diff --git a/include/linux/of_address.h b/include/linux/of_address.h index a1984dd037da..e20e3af68fb6 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h | |||
| @@ -28,11 +28,13 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } | |||
| 28 | #endif | 28 | #endif |
| 29 | 29 | ||
| 30 | #else /* CONFIG_OF_ADDRESS */ | 30 | #else /* CONFIG_OF_ADDRESS */ |
| 31 | #ifndef of_address_to_resource | ||
| 31 | static inline int of_address_to_resource(struct device_node *dev, int index, | 32 | static inline int of_address_to_resource(struct device_node *dev, int index, |
| 32 | struct resource *r) | 33 | struct resource *r) |
| 33 | { | 34 | { |
| 34 | return -EINVAL; | 35 | return -EINVAL; |
| 35 | } | 36 | } |
| 37 | #endif | ||
| 36 | static inline struct device_node *of_find_matching_node_by_address( | 38 | static inline struct device_node *of_find_matching_node_by_address( |
| 37 | struct device_node *from, | 39 | struct device_node *from, |
| 38 | const struct of_device_id *matches, | 40 | const struct of_device_id *matches, |
diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h index f2dc6d8fc680..38a993508327 100644 --- a/include/linux/ptp_clock_kernel.h +++ b/include/linux/ptp_clock_kernel.h | |||
| @@ -54,7 +54,8 @@ struct ptp_clock_request { | |||
| 54 | * clock operations | 54 | * clock operations |
| 55 | * | 55 | * |
| 56 | * @adjfreq: Adjusts the frequency of the hardware clock. | 56 | * @adjfreq: Adjusts the frequency of the hardware clock. |
| 57 | * parameter delta: Desired period change in parts per billion. | 57 | * parameter delta: Desired frequency offset from nominal frequency |
| 58 | * in parts per billion | ||
| 58 | * | 59 | * |
| 59 | * @adjtime: Shifts the time of the hardware clock. | 60 | * @adjtime: Shifts the time of the hardware clock. |
| 60 | * parameter delta: Desired change in nanoseconds. | 61 | * parameter delta: Desired change in nanoseconds. |
diff --git a/include/xen/hvm.h b/include/xen/hvm.h index b193fa2f9fdd..13e43e41637d 100644 --- a/include/xen/hvm.h +++ b/include/xen/hvm.h | |||
| @@ -5,6 +5,36 @@ | |||
| 5 | #include <xen/interface/hvm/params.h> | 5 | #include <xen/interface/hvm/params.h> |
| 6 | #include <asm/xen/hypercall.h> | 6 | #include <asm/xen/hypercall.h> |
| 7 | 7 | ||
| 8 | static const char *param_name(int op) | ||
| 9 | { | ||
| 10 | #define PARAM(x) [HVM_PARAM_##x] = #x | ||
| 11 | static const char *const names[] = { | ||
| 12 | PARAM(CALLBACK_IRQ), | ||
| 13 | PARAM(STORE_PFN), | ||
| 14 | PARAM(STORE_EVTCHN), | ||
| 15 | PARAM(PAE_ENABLED), | ||
| 16 | PARAM(IOREQ_PFN), | ||
| 17 | PARAM(BUFIOREQ_PFN), | ||
| 18 | PARAM(TIMER_MODE), | ||
| 19 | PARAM(HPET_ENABLED), | ||
| 20 | PARAM(IDENT_PT), | ||
| 21 | PARAM(DM_DOMAIN), | ||
| 22 | PARAM(ACPI_S_STATE), | ||
| 23 | PARAM(VM86_TSS), | ||
| 24 | PARAM(VPT_ALIGN), | ||
| 25 | PARAM(CONSOLE_PFN), | ||
| 26 | PARAM(CONSOLE_EVTCHN), | ||
| 27 | }; | ||
| 28 | #undef PARAM | ||
| 29 | |||
| 30 | if (op >= ARRAY_SIZE(names)) | ||
| 31 | return "unknown"; | ||
| 32 | |||
| 33 | if (!names[op]) | ||
| 34 | return "reserved"; | ||
| 35 | |||
| 36 | return names[op]; | ||
| 37 | } | ||
| 8 | static inline int hvm_get_parameter(int idx, uint64_t *value) | 38 | static inline int hvm_get_parameter(int idx, uint64_t *value) |
| 9 | { | 39 | { |
| 10 | struct xen_hvm_param xhv; | 40 | struct xen_hvm_param xhv; |
| @@ -14,8 +44,8 @@ static inline int hvm_get_parameter(int idx, uint64_t *value) | |||
| 14 | xhv.index = idx; | 44 | xhv.index = idx; |
| 15 | r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv); | 45 | r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv); |
| 16 | if (r < 0) { | 46 | if (r < 0) { |
| 17 | printk(KERN_ERR "Cannot get hvm parameter %d: %d!\n", | 47 | printk(KERN_ERR "Cannot get hvm parameter %s (%d): %d!\n", |
| 18 | idx, r); | 48 | param_name(idx), idx, r); |
| 19 | return r; | 49 | return r; |
| 20 | } | 50 | } |
| 21 | *value = xhv.value; | 51 | *value = xhv.value; |
diff --git a/kernel/futex.c b/kernel/futex.c index 3717e7b306e0..20ef219bbe9b 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
| @@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, | |||
| 716 | struct futex_pi_state **ps, | 716 | struct futex_pi_state **ps, |
| 717 | struct task_struct *task, int set_waiters) | 717 | struct task_struct *task, int set_waiters) |
| 718 | { | 718 | { |
| 719 | int lock_taken, ret, ownerdied = 0; | 719 | int lock_taken, ret, force_take = 0; |
| 720 | u32 uval, newval, curval, vpid = task_pid_vnr(task); | 720 | u32 uval, newval, curval, vpid = task_pid_vnr(task); |
| 721 | 721 | ||
| 722 | retry: | 722 | retry: |
| @@ -755,17 +755,15 @@ retry: | |||
| 755 | newval = curval | FUTEX_WAITERS; | 755 | newval = curval | FUTEX_WAITERS; |
| 756 | 756 | ||
| 757 | /* | 757 | /* |
| 758 | * There are two cases, where a futex might have no owner (the | 758 | * Should we force take the futex? See below. |
| 759 | * owner TID is 0): OWNER_DIED. We take over the futex in this | ||
| 760 | * case. We also do an unconditional take over, when the owner | ||
| 761 | * of the futex died. | ||
| 762 | * | ||
| 763 | * This is safe as we are protected by the hash bucket lock ! | ||
| 764 | */ | 759 | */ |
| 765 | if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { | 760 | if (unlikely(force_take)) { |
| 766 | /* Keep the OWNER_DIED bit */ | 761 | /* |
| 762 | * Keep the OWNER_DIED and the WAITERS bit and set the | ||
| 763 | * new TID value. | ||
| 764 | */ | ||
| 767 | newval = (curval & ~FUTEX_TID_MASK) | vpid; | 765 | newval = (curval & ~FUTEX_TID_MASK) | vpid; |
| 768 | ownerdied = 0; | 766 | force_take = 0; |
| 769 | lock_taken = 1; | 767 | lock_taken = 1; |
| 770 | } | 768 | } |
| 771 | 769 | ||
| @@ -775,7 +773,7 @@ retry: | |||
| 775 | goto retry; | 773 | goto retry; |
| 776 | 774 | ||
| 777 | /* | 775 | /* |
| 778 | * We took the lock due to owner died take over. | 776 | * We took the lock due to forced take over. |
| 779 | */ | 777 | */ |
| 780 | if (unlikely(lock_taken)) | 778 | if (unlikely(lock_taken)) |
| 781 | return 1; | 779 | return 1; |
| @@ -790,20 +788,25 @@ retry: | |||
| 790 | switch (ret) { | 788 | switch (ret) { |
| 791 | case -ESRCH: | 789 | case -ESRCH: |
| 792 | /* | 790 | /* |
| 793 | * No owner found for this futex. Check if the | 791 | * We failed to find an owner for this |
| 794 | * OWNER_DIED bit is set to figure out whether | 792 | * futex. So we have no pi_state to block |
| 795 | * this is a robust futex or not. | 793 | * on. This can happen in two cases: |
| 794 | * | ||
| 795 | * 1) The owner died | ||
| 796 | * 2) A stale FUTEX_WAITERS bit | ||
| 797 | * | ||
| 798 | * Re-read the futex value. | ||
| 796 | */ | 799 | */ |
| 797 | if (get_futex_value_locked(&curval, uaddr)) | 800 | if (get_futex_value_locked(&curval, uaddr)) |
| 798 | return -EFAULT; | 801 | return -EFAULT; |
| 799 | 802 | ||
| 800 | /* | 803 | /* |
| 801 | * We simply start over in case of a robust | 804 | * If the owner died or we have a stale |
| 802 | * futex. The code above will take the futex | 805 | * WAITERS bit the owner TID in the user space |
| 803 | * and return happy. | 806 | * futex is 0. |
| 804 | */ | 807 | */ |
| 805 | if (curval & FUTEX_OWNER_DIED) { | 808 | if (!(curval & FUTEX_TID_MASK)) { |
| 806 | ownerdied = 1; | 809 | force_take = 1; |
| 807 | goto retry; | 810 | goto retry; |
| 808 | } | 811 | } |
| 809 | default: | 812 | default: |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index ccd985da6518..1f4a32bb2971 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
| @@ -941,6 +941,13 @@ static int hidp_setup_hid(struct hidp_session *session, | |||
| 941 | hid->hid_get_raw_report = hidp_get_raw_report; | 941 | hid->hid_get_raw_report = hidp_get_raw_report; |
| 942 | hid->hid_output_raw_report = hidp_output_raw_report; | 942 | hid->hid_output_raw_report = hidp_output_raw_report; |
| 943 | 943 | ||
| 944 | /* True if device is blacklisted in drivers/hid/hid-core.c */ | ||
| 945 | if (hid_ignore(hid)) { | ||
| 946 | hid_destroy_device(session->hid); | ||
| 947 | session->hid = NULL; | ||
| 948 | return -ENODEV; | ||
| 949 | } | ||
| 950 | |||
| 944 | return 0; | 951 | return 0; |
| 945 | 952 | ||
| 946 | fault: | 953 | fault: |
| @@ -1013,7 +1020,7 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
| 1013 | 1020 | ||
| 1014 | if (req->rd_size > 0) { | 1021 | if (req->rd_size > 0) { |
| 1015 | err = hidp_setup_hid(session, req); | 1022 | err = hidp_setup_hid(session, req); |
| 1016 | if (err) | 1023 | if (err && err != -ENODEV) |
| 1017 | goto purge; | 1024 | goto purge; |
| 1018 | } | 1025 | } |
| 1019 | 1026 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 09cb3f6dc40c..bda6d004f9f0 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1666,7 +1666,7 @@ static inline int deliver_skb(struct sk_buff *skb, | |||
| 1666 | 1666 | ||
| 1667 | static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) | 1667 | static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) |
| 1668 | { | 1668 | { |
| 1669 | if (ptype->af_packet_priv == NULL) | 1669 | if (!ptype->af_packet_priv || !skb->sk) |
| 1670 | return false; | 1670 | return false; |
| 1671 | 1671 | ||
| 1672 | if (ptype->id_match) | 1672 | if (ptype->id_match) |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 76d4c2c3c89b..fad649ae4dec 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -2192,7 +2192,8 @@ static int nlmsg_populate_fdb(struct sk_buff *skb, | |||
| 2192 | goto skip; | 2192 | goto skip; |
| 2193 | 2193 | ||
| 2194 | err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, | 2194 | err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, |
| 2195 | portid, seq, 0, NTF_SELF); | 2195 | portid, seq, |
| 2196 | RTM_NEWNEIGH, NTF_SELF); | ||
| 2196 | if (err < 0) | 2197 | if (err < 0) |
| 2197 | return err; | 2198 | return err; |
| 2198 | skip: | 2199 | skip: |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 535584c00f91..0c34bfabc11f 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -892,13 +892,16 @@ static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, | |||
| 892 | struct inet_diag_req_v2 *r, struct nlattr *bc) | 892 | struct inet_diag_req_v2 *r, struct nlattr *bc) |
| 893 | { | 893 | { |
| 894 | const struct inet_diag_handler *handler; | 894 | const struct inet_diag_handler *handler; |
| 895 | int err = 0; | ||
| 895 | 896 | ||
| 896 | handler = inet_diag_lock_handler(r->sdiag_protocol); | 897 | handler = inet_diag_lock_handler(r->sdiag_protocol); |
| 897 | if (!IS_ERR(handler)) | 898 | if (!IS_ERR(handler)) |
| 898 | handler->dump(skb, cb, r, bc); | 899 | handler->dump(skb, cb, r, bc); |
| 900 | else | ||
| 901 | err = PTR_ERR(handler); | ||
| 899 | inet_diag_unlock_handler(handler); | 902 | inet_diag_unlock_handler(handler); |
| 900 | 903 | ||
| 901 | return skb->len; | 904 | return err ? : skb->len; |
| 902 | } | 905 | } |
| 903 | 906 | ||
| 904 | static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) | 907 | static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 0185679c5f53..d5cb3c4e66f8 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
| @@ -1633,9 +1633,9 @@ static size_t ip6gre_get_size(const struct net_device *dev) | |||
| 1633 | /* IFLA_GRE_OKEY */ | 1633 | /* IFLA_GRE_OKEY */ |
| 1634 | nla_total_size(4) + | 1634 | nla_total_size(4) + |
| 1635 | /* IFLA_GRE_LOCAL */ | 1635 | /* IFLA_GRE_LOCAL */ |
| 1636 | nla_total_size(4) + | 1636 | nla_total_size(sizeof(struct in6_addr)) + |
| 1637 | /* IFLA_GRE_REMOTE */ | 1637 | /* IFLA_GRE_REMOTE */ |
| 1638 | nla_total_size(4) + | 1638 | nla_total_size(sizeof(struct in6_addr)) + |
| 1639 | /* IFLA_GRE_TTL */ | 1639 | /* IFLA_GRE_TTL */ |
| 1640 | nla_total_size(1) + | 1640 | nla_total_size(1) + |
| 1641 | /* IFLA_GRE_TOS */ | 1641 | /* IFLA_GRE_TOS */ |
| @@ -1659,8 +1659,8 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev) | |||
| 1659 | nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) || | 1659 | nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) || |
| 1660 | nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || | 1660 | nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || |
| 1661 | nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || | 1661 | nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || |
| 1662 | nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->raddr) || | 1662 | nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->laddr) || |
| 1663 | nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->laddr) || | 1663 | nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->raddr) || |
| 1664 | nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || | 1664 | nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || |
| 1665 | /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/ | 1665 | /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/ |
| 1666 | nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || | 1666 | nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index ff36194a71aa..2edce30ef733 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -535,7 +535,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) | |||
| 535 | { | 535 | { |
| 536 | struct inet6_dev *idev; | 536 | struct inet6_dev *idev; |
| 537 | struct inet6_ifaddr *ifa; | 537 | struct inet6_ifaddr *ifa; |
| 538 | struct in6_addr mcaddr; | 538 | struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT; |
| 539 | 539 | ||
| 540 | idev = in6_dev_get(dev); | 540 | idev = in6_dev_get(dev); |
| 541 | if (!idev) | 541 | if (!idev) |
| @@ -543,7 +543,6 @@ static void ndisc_send_unsol_na(struct net_device *dev) | |||
| 543 | 543 | ||
| 544 | read_lock_bh(&idev->lock); | 544 | read_lock_bh(&idev->lock); |
| 545 | list_for_each_entry(ifa, &idev->addr_list, if_list) { | 545 | list_for_each_entry(ifa, &idev->addr_list, if_list) { |
| 546 | addrconf_addr_solict_mult(&ifa->addr, &mcaddr); | ||
| 547 | ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, | 546 | ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, |
| 548 | /*router=*/ !!idev->cnf.forwarding, | 547 | /*router=*/ !!idev->cnf.forwarding, |
| 549 | /*solicited=*/ false, /*override=*/ true, | 548 | /*solicited=*/ false, /*override=*/ true, |
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index f0dd83cff906..9687fa1c2275 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c | |||
| @@ -84,18 +84,19 @@ | |||
| 84 | * grp->index is the index of the group; and grp->slot_shift | 84 | * grp->index is the index of the group; and grp->slot_shift |
| 85 | * is the shift for the corresponding (scaled) sigma_i. | 85 | * is the shift for the corresponding (scaled) sigma_i. |
| 86 | */ | 86 | */ |
| 87 | #define QFQ_MAX_INDEX 19 | 87 | #define QFQ_MAX_INDEX 24 |
| 88 | #define QFQ_MAX_WSHIFT 16 | 88 | #define QFQ_MAX_WSHIFT 12 |
| 89 | 89 | ||
| 90 | #define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT) | 90 | #define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT) |
| 91 | #define QFQ_MAX_WSUM (2*QFQ_MAX_WEIGHT) | 91 | #define QFQ_MAX_WSUM (16*QFQ_MAX_WEIGHT) |
| 92 | 92 | ||
| 93 | #define FRAC_BITS 30 /* fixed point arithmetic */ | 93 | #define FRAC_BITS 30 /* fixed point arithmetic */ |
| 94 | #define ONE_FP (1UL << FRAC_BITS) | 94 | #define ONE_FP (1UL << FRAC_BITS) |
| 95 | #define IWSUM (ONE_FP/QFQ_MAX_WSUM) | 95 | #define IWSUM (ONE_FP/QFQ_MAX_WSUM) |
| 96 | 96 | ||
| 97 | #define QFQ_MTU_SHIFT 11 | 97 | #define QFQ_MTU_SHIFT 16 /* to support TSO/GSO */ |
| 98 | #define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX) | 98 | #define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX) |
| 99 | #define QFQ_MIN_LMAX 256 /* min possible lmax for a class */ | ||
| 99 | 100 | ||
| 100 | /* | 101 | /* |
| 101 | * Possible group states. These values are used as indexes for the bitmaps | 102 | * Possible group states. These values are used as indexes for the bitmaps |
| @@ -231,6 +232,32 @@ static void qfq_update_class_params(struct qfq_sched *q, struct qfq_class *cl, | |||
| 231 | q->wsum += delta_w; | 232 | q->wsum += delta_w; |
| 232 | } | 233 | } |
| 233 | 234 | ||
| 235 | static void qfq_update_reactivate_class(struct qfq_sched *q, | ||
| 236 | struct qfq_class *cl, | ||
| 237 | u32 inv_w, u32 lmax, int delta_w) | ||
| 238 | { | ||
| 239 | bool need_reactivation = false; | ||
| 240 | int i = qfq_calc_index(inv_w, lmax); | ||
| 241 | |||
| 242 | if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { | ||
| 243 | /* | ||
| 244 | * shift cl->F back, to not charge the | ||
| 245 | * class for the not-yet-served head | ||
| 246 | * packet | ||
| 247 | */ | ||
| 248 | cl->F = cl->S; | ||
| 249 | /* remove class from its slot in the old group */ | ||
| 250 | qfq_deactivate_class(q, cl); | ||
| 251 | need_reactivation = true; | ||
| 252 | } | ||
| 253 | |||
| 254 | qfq_update_class_params(q, cl, lmax, inv_w, delta_w); | ||
| 255 | |||
| 256 | if (need_reactivation) /* activate in new group */ | ||
| 257 | qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); | ||
| 258 | } | ||
| 259 | |||
| 260 | |||
| 234 | static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | 261 | static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, |
| 235 | struct nlattr **tca, unsigned long *arg) | 262 | struct nlattr **tca, unsigned long *arg) |
| 236 | { | 263 | { |
| @@ -238,7 +265,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
| 238 | struct qfq_class *cl = (struct qfq_class *)*arg; | 265 | struct qfq_class *cl = (struct qfq_class *)*arg; |
| 239 | struct nlattr *tb[TCA_QFQ_MAX + 1]; | 266 | struct nlattr *tb[TCA_QFQ_MAX + 1]; |
| 240 | u32 weight, lmax, inv_w; | 267 | u32 weight, lmax, inv_w; |
| 241 | int i, err; | 268 | int err; |
| 242 | int delta_w; | 269 | int delta_w; |
| 243 | 270 | ||
| 244 | if (tca[TCA_OPTIONS] == NULL) { | 271 | if (tca[TCA_OPTIONS] == NULL) { |
| @@ -270,16 +297,14 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
| 270 | 297 | ||
| 271 | if (tb[TCA_QFQ_LMAX]) { | 298 | if (tb[TCA_QFQ_LMAX]) { |
| 272 | lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); | 299 | lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); |
| 273 | if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) { | 300 | if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) { |
| 274 | pr_notice("qfq: invalid max length %u\n", lmax); | 301 | pr_notice("qfq: invalid max length %u\n", lmax); |
| 275 | return -EINVAL; | 302 | return -EINVAL; |
| 276 | } | 303 | } |
| 277 | } else | 304 | } else |
| 278 | lmax = 1UL << QFQ_MTU_SHIFT; | 305 | lmax = psched_mtu(qdisc_dev(sch)); |
| 279 | 306 | ||
| 280 | if (cl != NULL) { | 307 | if (cl != NULL) { |
| 281 | bool need_reactivation = false; | ||
| 282 | |||
| 283 | if (tca[TCA_RATE]) { | 308 | if (tca[TCA_RATE]) { |
| 284 | err = gen_replace_estimator(&cl->bstats, &cl->rate_est, | 309 | err = gen_replace_estimator(&cl->bstats, &cl->rate_est, |
| 285 | qdisc_root_sleeping_lock(sch), | 310 | qdisc_root_sleeping_lock(sch), |
| @@ -291,24 +316,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
| 291 | if (lmax == cl->lmax && inv_w == cl->inv_w) | 316 | if (lmax == cl->lmax && inv_w == cl->inv_w) |
| 292 | return 0; /* nothing to update */ | 317 | return 0; /* nothing to update */ |
| 293 | 318 | ||
| 294 | i = qfq_calc_index(inv_w, lmax); | ||
| 295 | sch_tree_lock(sch); | 319 | sch_tree_lock(sch); |
| 296 | if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { | 320 | qfq_update_reactivate_class(q, cl, inv_w, lmax, delta_w); |
| 297 | /* | ||
| 298 | * shift cl->F back, to not charge the | ||
| 299 | * class for the not-yet-served head | ||
| 300 | * packet | ||
| 301 | */ | ||
| 302 | cl->F = cl->S; | ||
| 303 | /* remove class from its slot in the old group */ | ||
| 304 | qfq_deactivate_class(q, cl); | ||
| 305 | need_reactivation = true; | ||
| 306 | } | ||
| 307 | |||
| 308 | qfq_update_class_params(q, cl, lmax, inv_w, delta_w); | ||
| 309 | |||
| 310 | if (need_reactivation) /* activate in new group */ | ||
| 311 | qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); | ||
| 312 | sch_tree_unlock(sch); | 321 | sch_tree_unlock(sch); |
| 313 | 322 | ||
| 314 | return 0; | 323 | return 0; |
| @@ -663,15 +672,48 @@ static void qfq_make_eligible(struct qfq_sched *q, u64 old_V) | |||
| 663 | 672 | ||
| 664 | 673 | ||
| 665 | /* | 674 | /* |
| 666 | * XXX we should make sure that slot becomes less than 32. | 675 | * If the weight and lmax (max_pkt_size) of the classes do not change, |
| 667 | * This is guaranteed by the input values. | 676 | * then QFQ guarantees that the slot index is never higher than |
| 668 | * roundedS is always cl->S rounded on grp->slot_shift bits. | 677 | * 2 + ((1<<QFQ_MTU_SHIFT)/QFQ_MIN_LMAX) * (QFQ_MAX_WEIGHT/QFQ_MAX_WSUM). |
| 678 | * | ||
| 679 | * With the current values of the above constants, the index is | ||
| 680 | * then guaranteed to never be higher than 2 + 256 * (1 / 16) = 18. | ||
| 681 | * | ||
| 682 | * When the weight of a class is increased or the lmax of the class is | ||
| 683 | * decreased, a new class with smaller slot size may happen to be | ||
| 684 | * activated. The activation of this class should be properly delayed | ||
| 685 | * to when the service of the class has finished in the ideal system | ||
| 686 | * tracked by QFQ. If the activation of the class is not delayed to | ||
| 687 | * this reference time instant, then this class may be unjustly served | ||
| 688 | * before other classes waiting for service. This may cause | ||
| 689 | * (unfrequently) the above bound to the slot index to be violated for | ||
| 690 | * some of these unlucky classes. | ||
| 691 | * | ||
| 692 | * Instead of delaying the activation of the new class, which is quite | ||
| 693 | * complex, the following inaccurate but simple solution is used: if | ||
| 694 | * the slot index is higher than QFQ_MAX_SLOTS-2, then the timestamps | ||
| 695 | * of the class are shifted backward so as to let the slot index | ||
| 696 | * become equal to QFQ_MAX_SLOTS-2. This threshold is used because, if | ||
| 697 | * the slot index is above it, then the data structure implementing | ||
| 698 | * the bucket list either gets immediately corrupted or may get | ||
| 699 | * corrupted on a possible next packet arrival that causes the start | ||
| 700 | * time of the group to be shifted backward. | ||
| 669 | */ | 701 | */ |
| 670 | static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, | 702 | static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, |
| 671 | u64 roundedS) | 703 | u64 roundedS) |
| 672 | { | 704 | { |
| 673 | u64 slot = (roundedS - grp->S) >> grp->slot_shift; | 705 | u64 slot = (roundedS - grp->S) >> grp->slot_shift; |
| 674 | unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS; | 706 | unsigned int i; /* slot index in the bucket list */ |
| 707 | |||
| 708 | if (unlikely(slot > QFQ_MAX_SLOTS - 2)) { | ||
| 709 | u64 deltaS = roundedS - grp->S - | ||
| 710 | ((u64)(QFQ_MAX_SLOTS - 2)<<grp->slot_shift); | ||
| 711 | cl->S -= deltaS; | ||
| 712 | cl->F -= deltaS; | ||
| 713 | slot = QFQ_MAX_SLOTS - 2; | ||
| 714 | } | ||
| 715 | |||
| 716 | i = (grp->front + slot) % QFQ_MAX_SLOTS; | ||
| 675 | 717 | ||
| 676 | hlist_add_head(&cl->next, &grp->slots[i]); | 718 | hlist_add_head(&cl->next, &grp->slots[i]); |
| 677 | __set_bit(slot, &grp->full_slots); | 719 | __set_bit(slot, &grp->full_slots); |
| @@ -892,6 +934,13 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 892 | } | 934 | } |
| 893 | pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); | 935 | pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); |
| 894 | 936 | ||
| 937 | if (unlikely(cl->lmax < qdisc_pkt_len(skb))) { | ||
| 938 | pr_debug("qfq: increasing maxpkt from %u to %u for class %u", | ||
| 939 | cl->lmax, qdisc_pkt_len(skb), cl->common.classid); | ||
| 940 | qfq_update_reactivate_class(q, cl, cl->inv_w, | ||
| 941 | qdisc_pkt_len(skb), 0); | ||
| 942 | } | ||
| 943 | |||
| 895 | err = qdisc_enqueue(skb, cl->qdisc); | 944 | err = qdisc_enqueue(skb, cl->qdisc); |
| 896 | if (unlikely(err != NET_XMIT_SUCCESS)) { | 945 | if (unlikely(err != NET_XMIT_SUCCESS)) { |
| 897 | pr_debug("qfq_enqueue: enqueue failed %d\n", err); | 946 | pr_debug("qfq_enqueue: enqueue failed %d\n", err); |
diff --git a/net/tipc/handler.c b/net/tipc/handler.c index 111ff8300ae5..b36f0fcd9bdf 100644 --- a/net/tipc/handler.c +++ b/net/tipc/handler.c | |||
| @@ -116,7 +116,6 @@ void tipc_handler_stop(void) | |||
| 116 | return; | 116 | return; |
| 117 | 117 | ||
| 118 | handler_enabled = 0; | 118 | handler_enabled = 0; |
| 119 | tasklet_disable(&tipc_tasklet); | ||
| 120 | tasklet_kill(&tipc_tasklet); | 119 | tasklet_kill(&tipc_tasklet); |
| 121 | 120 | ||
| 122 | spin_lock_bh(&qitem_lock); | 121 | spin_lock_bh(&qitem_lock); |
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index bd2e09895553..cdd48600e02a 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h | |||
| @@ -12,7 +12,7 @@ extern "C" { | |||
| 12 | 12 | ||
| 13 | #include <assert.h> | 13 | #include <assert.h> |
| 14 | #include <stdio.h> | 14 | #include <stdio.h> |
| 15 | #include <sys/queue.h> | 15 | #include "list.h" |
| 16 | #ifndef __cplusplus | 16 | #ifndef __cplusplus |
| 17 | #include <stdbool.h> | 17 | #include <stdbool.h> |
| 18 | #endif | 18 | #endif |
| @@ -175,12 +175,11 @@ struct menu { | |||
| 175 | #define MENU_ROOT 0x0002 | 175 | #define MENU_ROOT 0x0002 |
| 176 | 176 | ||
| 177 | struct jump_key { | 177 | struct jump_key { |
| 178 | CIRCLEQ_ENTRY(jump_key) entries; | 178 | struct list_head entries; |
| 179 | size_t offset; | 179 | size_t offset; |
| 180 | struct menu *target; | 180 | struct menu *target; |
| 181 | int index; | 181 | int index; |
| 182 | }; | 182 | }; |
| 183 | CIRCLEQ_HEAD(jk_head, jump_key); | ||
| 184 | 183 | ||
| 185 | #define JUMP_NB 9 | 184 | #define JUMP_NB 9 |
| 186 | 185 | ||
diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h new file mode 100644 index 000000000000..0ae730be5f49 --- /dev/null +++ b/scripts/kconfig/list.h | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | #ifndef LIST_H | ||
| 2 | #define LIST_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copied from include/linux/... | ||
| 6 | */ | ||
| 7 | |||
| 8 | #undef offsetof | ||
| 9 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) | ||
| 10 | |||
| 11 | /** | ||
| 12 | * container_of - cast a member of a structure out to the containing structure | ||
| 13 | * @ptr: the pointer to the member. | ||
| 14 | * @type: the type of the container struct this is embedded in. | ||
| 15 | * @member: the name of the member within the struct. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | #define container_of(ptr, type, member) ({ \ | ||
| 19 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ | ||
| 20 | (type *)( (char *)__mptr - offsetof(type,member) );}) | ||
| 21 | |||
| 22 | |||
| 23 | struct list_head { | ||
| 24 | struct list_head *next, *prev; | ||
| 25 | }; | ||
| 26 | |||
| 27 | |||
| 28 | #define LIST_HEAD_INIT(name) { &(name), &(name) } | ||
| 29 | |||
| 30 | #define LIST_HEAD(name) \ | ||
| 31 | struct list_head name = LIST_HEAD_INIT(name) | ||
| 32 | |||
| 33 | /** | ||
| 34 | * list_entry - get the struct for this entry | ||
| 35 | * @ptr: the &struct list_head pointer. | ||
| 36 | * @type: the type of the struct this is embedded in. | ||
| 37 | * @member: the name of the list_struct within the struct. | ||
| 38 | */ | ||
| 39 | #define list_entry(ptr, type, member) \ | ||
| 40 | container_of(ptr, type, member) | ||
| 41 | |||
| 42 | /** | ||
| 43 | * list_for_each_entry - iterate over list of given type | ||
| 44 | * @pos: the type * to use as a loop cursor. | ||
| 45 | * @head: the head for your list. | ||
| 46 | * @member: the name of the list_struct within the struct. | ||
| 47 | */ | ||
| 48 | #define list_for_each_entry(pos, head, member) \ | ||
| 49 | for (pos = list_entry((head)->next, typeof(*pos), member); \ | ||
| 50 | &pos->member != (head); \ | ||
| 51 | pos = list_entry(pos->member.next, typeof(*pos), member)) | ||
| 52 | |||
| 53 | /** | ||
| 54 | * list_empty - tests whether a list is empty | ||
| 55 | * @head: the list to test. | ||
| 56 | */ | ||
| 57 | static inline int list_empty(const struct list_head *head) | ||
| 58 | { | ||
| 59 | return head->next == head; | ||
| 60 | } | ||
| 61 | |||
| 62 | /* | ||
| 63 | * Insert a new entry between two known consecutive entries. | ||
| 64 | * | ||
| 65 | * This is only for internal list manipulation where we know | ||
| 66 | * the prev/next entries already! | ||
| 67 | */ | ||
| 68 | static inline void __list_add(struct list_head *_new, | ||
| 69 | struct list_head *prev, | ||
| 70 | struct list_head *next) | ||
| 71 | { | ||
| 72 | next->prev = _new; | ||
| 73 | _new->next = next; | ||
| 74 | _new->prev = prev; | ||
| 75 | prev->next = _new; | ||
| 76 | } | ||
| 77 | |||
| 78 | /** | ||
| 79 | * list_add_tail - add a new entry | ||
| 80 | * @new: new entry to be added | ||
| 81 | * @head: list head to add it before | ||
| 82 | * | ||
| 83 | * Insert a new entry before the specified head. | ||
| 84 | * This is useful for implementing queues. | ||
| 85 | */ | ||
| 86 | static inline void list_add_tail(struct list_head *_new, struct list_head *head) | ||
| 87 | { | ||
| 88 | __list_add(_new, head->prev, head); | ||
| 89 | } | ||
| 90 | |||
| 91 | #endif | ||
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 1d1c08537f1e..ef1a7381f956 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h | |||
| @@ -21,9 +21,9 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu)); | |||
| 21 | P(menu_get_parent_menu,struct menu *,(struct menu *menu)); | 21 | P(menu_get_parent_menu,struct menu *,(struct menu *menu)); |
| 22 | P(menu_has_help,bool,(struct menu *menu)); | 22 | P(menu_has_help,bool,(struct menu *menu)); |
| 23 | P(menu_get_help,const char *,(struct menu *menu)); | 23 | P(menu_get_help,const char *,(struct menu *menu)); |
| 24 | P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head | 24 | P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head |
| 25 | *head)); | 25 | *head)); |
| 26 | P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head | 26 | P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head |
| 27 | *head)); | 27 | *head)); |
| 28 | P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); | 28 | P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); |
| 29 | 29 | ||
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 48f67448af7b..53975cf87608 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c | |||
| @@ -312,7 +312,7 @@ static void set_config_filename(const char *config_filename) | |||
| 312 | 312 | ||
| 313 | 313 | ||
| 314 | struct search_data { | 314 | struct search_data { |
| 315 | struct jk_head *head; | 315 | struct list_head *head; |
| 316 | struct menu **targets; | 316 | struct menu **targets; |
| 317 | int *keys; | 317 | int *keys; |
| 318 | }; | 318 | }; |
| @@ -323,7 +323,7 @@ static void update_text(char *buf, size_t start, size_t end, void *_data) | |||
| 323 | struct jump_key *pos; | 323 | struct jump_key *pos; |
| 324 | int k = 0; | 324 | int k = 0; |
| 325 | 325 | ||
| 326 | CIRCLEQ_FOREACH(pos, data->head, entries) { | 326 | list_for_each_entry(pos, data->head, entries) { |
| 327 | if (pos->offset >= start && pos->offset < end) { | 327 | if (pos->offset >= start && pos->offset < end) { |
| 328 | char header[4]; | 328 | char header[4]; |
| 329 | 329 | ||
| @@ -375,7 +375,7 @@ again: | |||
| 375 | 375 | ||
| 376 | sym_arr = sym_re_search(dialog_input); | 376 | sym_arr = sym_re_search(dialog_input); |
| 377 | do { | 377 | do { |
| 378 | struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head); | 378 | LIST_HEAD(head); |
| 379 | struct menu *targets[JUMP_NB]; | 379 | struct menu *targets[JUMP_NB]; |
| 380 | int keys[JUMP_NB + 1], i; | 380 | int keys[JUMP_NB + 1], i; |
| 381 | struct search_data data = { | 381 | struct search_data data = { |
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index a3cade659f89..e98a05c8e508 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c | |||
| @@ -508,7 +508,7 @@ const char *menu_get_help(struct menu *menu) | |||
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | static void get_prompt_str(struct gstr *r, struct property *prop, | 510 | static void get_prompt_str(struct gstr *r, struct property *prop, |
| 511 | struct jk_head *head) | 511 | struct list_head *head) |
| 512 | { | 512 | { |
| 513 | int i, j; | 513 | int i, j; |
| 514 | struct menu *submenu[8], *menu, *location = NULL; | 514 | struct menu *submenu[8], *menu, *location = NULL; |
| @@ -544,12 +544,13 @@ static void get_prompt_str(struct gstr *r, struct property *prop, | |||
| 544 | } else | 544 | } else |
| 545 | jump->target = location; | 545 | jump->target = location; |
| 546 | 546 | ||
| 547 | if (CIRCLEQ_EMPTY(head)) | 547 | if (list_empty(head)) |
| 548 | jump->index = 0; | 548 | jump->index = 0; |
| 549 | else | 549 | else |
| 550 | jump->index = CIRCLEQ_LAST(head)->index + 1; | 550 | jump->index = list_entry(head->prev, struct jump_key, |
| 551 | entries)->index + 1; | ||
| 551 | 552 | ||
| 552 | CIRCLEQ_INSERT_TAIL(head, jump, entries); | 553 | list_add_tail(&jump->entries, head); |
| 553 | } | 554 | } |
| 554 | 555 | ||
| 555 | if (i > 0) { | 556 | if (i > 0) { |
| @@ -573,7 +574,8 @@ static void get_prompt_str(struct gstr *r, struct property *prop, | |||
| 573 | /* | 574 | /* |
| 574 | * head is optional and may be NULL | 575 | * head is optional and may be NULL |
| 575 | */ | 576 | */ |
| 576 | void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head) | 577 | void get_symbol_str(struct gstr *r, struct symbol *sym, |
| 578 | struct list_head *head) | ||
| 577 | { | 579 | { |
| 578 | bool hit; | 580 | bool hit; |
| 579 | struct property *prop; | 581 | struct property *prop; |
| @@ -612,7 +614,7 @@ void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head) | |||
| 612 | str_append(r, "\n\n"); | 614 | str_append(r, "\n\n"); |
| 613 | } | 615 | } |
| 614 | 616 | ||
| 615 | struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head) | 617 | struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) |
| 616 | { | 618 | { |
| 617 | struct symbol *sym; | 619 | struct symbol *sym; |
| 618 | struct gstr res = str_new(); | 620 | struct gstr res = str_new(); |
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 842c254396db..b08d20c66c2e 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
| @@ -164,8 +164,8 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup) | |||
| 164 | struct dev_exception_item *ex, *tmp; | 164 | struct dev_exception_item *ex, *tmp; |
| 165 | 165 | ||
| 166 | list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) { | 166 | list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) { |
| 167 | list_del(&ex->list); | 167 | list_del_rcu(&ex->list); |
| 168 | kfree(ex); | 168 | kfree_rcu(ex, rcu); |
| 169 | } | 169 | } |
| 170 | } | 170 | } |
| 171 | 171 | ||
| @@ -298,7 +298,7 @@ static int may_access(struct dev_cgroup *dev_cgroup, | |||
| 298 | struct dev_exception_item *ex; | 298 | struct dev_exception_item *ex; |
| 299 | bool match = false; | 299 | bool match = false; |
| 300 | 300 | ||
| 301 | list_for_each_entry(ex, &dev_cgroup->exceptions, list) { | 301 | list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) { |
| 302 | if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK)) | 302 | if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK)) |
| 303 | continue; | 303 | continue; |
| 304 | if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR)) | 304 | if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR)) |
| @@ -352,6 +352,8 @@ static int parent_has_perm(struct dev_cgroup *childcg, | |||
| 352 | */ | 352 | */ |
| 353 | static inline int may_allow_all(struct dev_cgroup *parent) | 353 | static inline int may_allow_all(struct dev_cgroup *parent) |
| 354 | { | 354 | { |
| 355 | if (!parent) | ||
| 356 | return 1; | ||
| 355 | return parent->behavior == DEVCG_DEFAULT_ALLOW; | 357 | return parent->behavior == DEVCG_DEFAULT_ALLOW; |
| 356 | } | 358 | } |
| 357 | 359 | ||
| @@ -376,11 +378,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
| 376 | int count, rc; | 378 | int count, rc; |
| 377 | struct dev_exception_item ex; | 379 | struct dev_exception_item ex; |
| 378 | struct cgroup *p = devcgroup->css.cgroup; | 380 | struct cgroup *p = devcgroup->css.cgroup; |
| 379 | struct dev_cgroup *parent = cgroup_to_devcgroup(p->parent); | 381 | struct dev_cgroup *parent = NULL; |
| 380 | 382 | ||
| 381 | if (!capable(CAP_SYS_ADMIN)) | 383 | if (!capable(CAP_SYS_ADMIN)) |
| 382 | return -EPERM; | 384 | return -EPERM; |
| 383 | 385 | ||
| 386 | if (p->parent) | ||
| 387 | parent = cgroup_to_devcgroup(p->parent); | ||
| 388 | |||
| 384 | memset(&ex, 0, sizeof(ex)); | 389 | memset(&ex, 0, sizeof(ex)); |
| 385 | b = buffer; | 390 | b = buffer; |
| 386 | 391 | ||
| @@ -391,11 +396,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
| 391 | if (!may_allow_all(parent)) | 396 | if (!may_allow_all(parent)) |
| 392 | return -EPERM; | 397 | return -EPERM; |
| 393 | dev_exception_clean(devcgroup); | 398 | dev_exception_clean(devcgroup); |
| 399 | devcgroup->behavior = DEVCG_DEFAULT_ALLOW; | ||
| 400 | if (!parent) | ||
| 401 | break; | ||
| 402 | |||
| 394 | rc = dev_exceptions_copy(&devcgroup->exceptions, | 403 | rc = dev_exceptions_copy(&devcgroup->exceptions, |
| 395 | &parent->exceptions); | 404 | &parent->exceptions); |
| 396 | if (rc) | 405 | if (rc) |
| 397 | return rc; | 406 | return rc; |
| 398 | devcgroup->behavior = DEVCG_DEFAULT_ALLOW; | ||
| 399 | break; | 407 | break; |
| 400 | case DEVCG_DENY: | 408 | case DEVCG_DENY: |
| 401 | dev_exception_clean(devcgroup); | 409 | dev_exception_clean(devcgroup); |
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index a9a2e63c0222..e8a1d18774b2 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c | |||
| @@ -76,6 +76,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) | |||
| 76 | snd_card_unref(card); | 76 | snd_card_unref(card); |
| 77 | return -EFAULT; | 77 | return -EFAULT; |
| 78 | } | 78 | } |
| 79 | snd_card_unref(card); | ||
| 79 | return 0; | 80 | return 0; |
| 80 | } | 81 | } |
| 81 | 82 | ||
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index f337b66a020b..4c1cc51772e6 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
| @@ -2454,6 +2454,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) | |||
| 2454 | mutex_unlock(&pcm->open_mutex); | 2454 | mutex_unlock(&pcm->open_mutex); |
| 2455 | if (err < 0) | 2455 | if (err < 0) |
| 2456 | goto __error; | 2456 | goto __error; |
| 2457 | snd_card_unref(pcm->card); | ||
| 2457 | return err; | 2458 | return err; |
| 2458 | 2459 | ||
| 2459 | __error: | 2460 | __error: |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 6e8872de5ba0..f9ddecf2f4cd 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
| @@ -2122,7 +2122,8 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file) | |||
| 2122 | pcm = snd_lookup_minor_data(iminor(inode), | 2122 | pcm = snd_lookup_minor_data(iminor(inode), |
| 2123 | SNDRV_DEVICE_TYPE_PCM_PLAYBACK); | 2123 | SNDRV_DEVICE_TYPE_PCM_PLAYBACK); |
| 2124 | err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); | 2124 | err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); |
| 2125 | snd_card_unref(pcm->card); | 2125 | if (pcm) |
| 2126 | snd_card_unref(pcm->card); | ||
| 2126 | return err; | 2127 | return err; |
| 2127 | } | 2128 | } |
| 2128 | 2129 | ||
| @@ -2135,7 +2136,8 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file) | |||
| 2135 | pcm = snd_lookup_minor_data(iminor(inode), | 2136 | pcm = snd_lookup_minor_data(iminor(inode), |
| 2136 | SNDRV_DEVICE_TYPE_PCM_CAPTURE); | 2137 | SNDRV_DEVICE_TYPE_PCM_CAPTURE); |
| 2137 | err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); | 2138 | err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); |
| 2138 | snd_card_unref(pcm->card); | 2139 | if (pcm) |
| 2140 | snd_card_unref(pcm->card); | ||
| 2139 | return err; | 2141 | return err; |
| 2140 | } | 2142 | } |
| 2141 | 2143 | ||
diff --git a/sound/core/sound.c b/sound/core/sound.c index 89780c323f19..70ccdab74153 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
| @@ -114,7 +114,7 @@ void *snd_lookup_minor_data(unsigned int minor, int type) | |||
| 114 | mreg = snd_minors[minor]; | 114 | mreg = snd_minors[minor]; |
| 115 | if (mreg && mreg->type == type) { | 115 | if (mreg && mreg->type == type) { |
| 116 | private_data = mreg->private_data; | 116 | private_data = mreg->private_data; |
| 117 | if (mreg->card_ptr) | 117 | if (private_data && mreg->card_ptr) |
| 118 | atomic_inc(&mreg->card_ptr->refcount); | 118 | atomic_inc(&mreg->card_ptr->refcount); |
| 119 | } else | 119 | } else |
| 120 | private_data = NULL; | 120 | private_data = NULL; |
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index e1d79ee35906..726a49ac9725 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c | |||
| @@ -54,7 +54,7 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type) | |||
| 54 | mreg = snd_oss_minors[minor]; | 54 | mreg = snd_oss_minors[minor]; |
| 55 | if (mreg && mreg->type == type) { | 55 | if (mreg && mreg->type == type) { |
| 56 | private_data = mreg->private_data; | 56 | private_data = mreg->private_data; |
| 57 | if (mreg->card_ptr) | 57 | if (private_data && mreg->card_ptr) |
| 58 | atomic_inc(&mreg->card_ptr->refcount); | 58 | atomic_inc(&mreg->card_ptr->refcount); |
| 59 | } else | 59 | } else |
| 60 | private_data = NULL; | 60 | private_data = NULL; |
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c index ef68d710d08c..e04e750a77ed 100644 --- a/sound/i2c/other/ak4113.c +++ b/sound/i2c/other/ak4113.c | |||
| @@ -426,7 +426,7 @@ static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = { | |||
| 426 | }, | 426 | }, |
| 427 | { | 427 | { |
| 428 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 428 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 429 | .name = "IEC958 Preample Capture Default", | 429 | .name = "IEC958 Preamble Capture Default", |
| 430 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | 430 | .access = SNDRV_CTL_ELEM_ACCESS_READ | |
| 431 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 431 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
| 432 | .info = snd_ak4113_spdif_pinfo, | 432 | .info = snd_ak4113_spdif_pinfo, |
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c index 816e7d225fb0..5bf4fca19e48 100644 --- a/sound/i2c/other/ak4114.c +++ b/sound/i2c/other/ak4114.c | |||
| @@ -401,7 +401,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { | |||
| 401 | }, | 401 | }, |
| 402 | { | 402 | { |
| 403 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 403 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 404 | .name = "IEC958 Preample Capture Default", | 404 | .name = "IEC958 Preamble Capture Default", |
| 405 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 405 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
| 406 | .info = snd_ak4114_spdif_pinfo, | 406 | .info = snd_ak4114_spdif_pinfo, |
| 407 | .get = snd_ak4114_spdif_pget, | 407 | .get = snd_ak4114_spdif_pget, |
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c index b4b2a51fc117..40e33c9f2b09 100644 --- a/sound/i2c/other/ak4117.c +++ b/sound/i2c/other/ak4117.c | |||
| @@ -380,7 +380,7 @@ static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = { | |||
| 380 | }, | 380 | }, |
| 381 | { | 381 | { |
| 382 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 382 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 383 | .name = "IEC958 Preample Capture Default", | 383 | .name = "IEC958 Preamble Capture Default", |
| 384 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | 384 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
| 385 | .info = snd_ak4117_spdif_pinfo, | 385 | .info = snd_ak4117_spdif_pinfo, |
| 386 | .get = snd_ak4117_spdif_pget, | 386 | .get = snd_ak4117_spdif_pget, |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 5d0e568fdea1..7266020c16cb 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
| @@ -2581,9 +2581,14 @@ static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea) | |||
| 2581 | struct es1968 *chip = tea->private_data; | 2581 | struct es1968 *chip = tea->private_data; |
| 2582 | unsigned long io = chip->io_port + GPIO_DATA; | 2582 | unsigned long io = chip->io_port + GPIO_DATA; |
| 2583 | u16 val = inw(io); | 2583 | u16 val = inw(io); |
| 2584 | u8 ret; | ||
| 2584 | 2585 | ||
| 2585 | return (val & STR_DATA) ? TEA575X_DATA : 0 | | 2586 | ret = 0; |
| 2586 | (val & STR_MOST) ? TEA575X_MOST : 0; | 2587 | if (val & STR_DATA) |
| 2588 | ret |= TEA575X_DATA; | ||
| 2589 | if (val & STR_MOST) | ||
| 2590 | ret |= TEA575X_MOST; | ||
| 2591 | return ret; | ||
| 2587 | } | 2592 | } |
| 2588 | 2593 | ||
| 2589 | static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output) | 2594 | static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output) |
| @@ -2655,6 +2660,8 @@ static struct ess_device_list pm_whitelist[] __devinitdata = { | |||
| 2655 | { TYPE_MAESTRO2E, 0x1179 }, | 2660 | { TYPE_MAESTRO2E, 0x1179 }, |
| 2656 | { TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */ | 2661 | { TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */ |
| 2657 | { TYPE_MAESTRO2E, 0x1558 }, | 2662 | { TYPE_MAESTRO2E, 0x1558 }, |
| 2663 | { TYPE_MAESTRO2E, 0x125d }, /* a PCI card, e.g. Terratec DMX */ | ||
| 2664 | { TYPE_MAESTRO2, 0x125d }, /* a PCI card, e.g. SF64-PCE2 */ | ||
| 2658 | }; | 2665 | }; |
| 2659 | 2666 | ||
| 2660 | static struct ess_device_list mpu_blacklist[] __devinitdata = { | 2667 | static struct ess_device_list mpu_blacklist[] __devinitdata = { |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index cc2e91d15538..c5806f89be1e 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
| @@ -767,9 +767,14 @@ static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea) | |||
| 767 | struct fm801 *chip = tea->private_data; | 767 | struct fm801 *chip = tea->private_data; |
| 768 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); | 768 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); |
| 769 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); | 769 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); |
| 770 | 770 | u8 ret; | |
| 771 | return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 | | 771 | |
| 772 | (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0; | 772 | ret = 0; |
| 773 | if (reg & FM801_GPIO_GP(gpio.data)) | ||
| 774 | ret |= TEA575X_DATA; | ||
| 775 | if (reg & FM801_GPIO_GP(gpio.most)) | ||
| 776 | ret |= TEA575X_MOST; | ||
| 777 | return ret; | ||
| 773 | } | 778 | } |
| 774 | 779 | ||
| 775 | static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output) | 780 | static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output) |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 72b085ae7d46..cd2dbaf1be78 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -3563,6 +3563,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
| 3563 | /* Teradici */ | 3563 | /* Teradici */ |
| 3564 | { PCI_DEVICE(0x6549, 0x1200), | 3564 | { PCI_DEVICE(0x6549, 0x1200), |
| 3565 | .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, | 3565 | .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, |
| 3566 | { PCI_DEVICE(0x6549, 0x2200), | ||
| 3567 | .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, | ||
| 3566 | /* Creative X-Fi (CA0110-IBG) */ | 3568 | /* Creative X-Fi (CA0110-IBG) */ |
| 3567 | /* CTHDA chips */ | 3569 | /* CTHDA chips */ |
| 3568 | { PCI_DEVICE(0x1102, 0x0010), | 3570 | { PCI_DEVICE(0x1102, 0x0010), |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index cdd43eadbc67..1eeba7386666 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
| @@ -545,6 +545,7 @@ static int ad198x_build_pcms(struct hda_codec *codec) | |||
| 545 | if (spec->multiout.dig_out_nid) { | 545 | if (spec->multiout.dig_out_nid) { |
| 546 | info++; | 546 | info++; |
| 547 | codec->num_pcms++; | 547 | codec->num_pcms++; |
| 548 | codec->spdif_status_reset = 1; | ||
| 548 | info->name = "AD198x Digital"; | 549 | info->name = "AD198x Digital"; |
| 549 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | 550 | info->pcm_type = HDA_PCM_TYPE_SPDIF; |
| 550 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; | 551 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 61a71131711c..d5f3a26d608d 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
| @@ -101,8 +101,8 @@ enum { | |||
| 101 | #define CS420X_VENDOR_NID 0x11 | 101 | #define CS420X_VENDOR_NID 0x11 |
| 102 | #define CS_DIG_OUT1_PIN_NID 0x10 | 102 | #define CS_DIG_OUT1_PIN_NID 0x10 |
| 103 | #define CS_DIG_OUT2_PIN_NID 0x15 | 103 | #define CS_DIG_OUT2_PIN_NID 0x15 |
| 104 | #define CS_DMIC1_PIN_NID 0x12 | 104 | #define CS_DMIC1_PIN_NID 0x0e |
| 105 | #define CS_DMIC2_PIN_NID 0x0e | 105 | #define CS_DMIC2_PIN_NID 0x12 |
| 106 | 106 | ||
| 107 | /* coef indices */ | 107 | /* coef indices */ |
| 108 | #define IDX_SPDIF_STAT 0x0000 | 108 | #define IDX_SPDIF_STAT 0x0000 |
| @@ -1079,14 +1079,18 @@ static void init_input(struct hda_codec *codec) | |||
| 1079 | cs_automic(codec, NULL); | 1079 | cs_automic(codec, NULL); |
| 1080 | 1080 | ||
| 1081 | coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ | 1081 | coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ |
| 1082 | cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); | ||
| 1083 | |||
| 1084 | coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG); | ||
| 1082 | if (is_active_pin(codec, CS_DMIC2_PIN_NID)) | 1085 | if (is_active_pin(codec, CS_DMIC2_PIN_NID)) |
| 1083 | coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */ | 1086 | coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */ |
| 1084 | if (is_active_pin(codec, CS_DMIC1_PIN_NID)) | 1087 | if (is_active_pin(codec, CS_DMIC1_PIN_NID)) |
| 1085 | coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off | 1088 | coef |= 1 << 3; /* DMIC1 2 chan on, GPIO0 off |
| 1086 | * No effect if SPDIF_OUT2 is | 1089 | * No effect if SPDIF_OUT2 is |
| 1087 | * selected in IDX_SPDIF_CTL. | 1090 | * selected in IDX_SPDIF_CTL. |
| 1088 | */ | 1091 | */ |
| 1089 | cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); | 1092 | |
| 1093 | cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef); | ||
| 1090 | } else { | 1094 | } else { |
| 1091 | if (spec->mic_detect) | 1095 | if (spec->mic_detect) |
| 1092 | cs_automic(codec, NULL); | 1096 | cs_automic(codec, NULL); |
| @@ -1107,7 +1111,7 @@ static const struct hda_verb cs_coef_init_verbs[] = { | |||
| 1107 | | 0x0400 /* Disable Coefficient Auto increment */ | 1111 | | 0x0400 /* Disable Coefficient Auto increment */ |
| 1108 | )}, | 1112 | )}, |
| 1109 | /* Beep */ | 1113 | /* Beep */ |
| 1110 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, | 1114 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG}, |
| 1111 | {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ | 1115 | {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ |
| 1112 | 1116 | ||
| 1113 | {} /* terminator */ | 1117 | {} /* terminator */ |
| @@ -1728,8 +1732,7 @@ static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
| 1728 | 1732 | ||
| 1729 | } | 1733 | } |
| 1730 | 1734 | ||
| 1731 | static struct snd_kcontrol_new cs421x_capture_source = { | 1735 | static const struct snd_kcontrol_new cs421x_capture_source = { |
| 1732 | |||
| 1733 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1736 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 1734 | .name = "Capture Source", | 1737 | .name = "Capture Source", |
| 1735 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 1738 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
| @@ -1946,7 +1949,7 @@ static int cs421x_suspend(struct hda_codec *codec) | |||
| 1946 | } | 1949 | } |
| 1947 | #endif | 1950 | #endif |
| 1948 | 1951 | ||
| 1949 | static struct hda_codec_ops cs421x_patch_ops = { | 1952 | static const struct hda_codec_ops cs421x_patch_ops = { |
| 1950 | .build_controls = cs421x_build_controls, | 1953 | .build_controls = cs421x_build_controls, |
| 1951 | .build_pcms = cs_build_pcms, | 1954 | .build_pcms = cs_build_pcms, |
| 1952 | .init = cs421x_init, | 1955 | .init = cs421x_init, |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f7397ad02a0d..68fd49294b26 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -5407,6 +5407,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
| 5407 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), | 5407 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), |
| 5408 | SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), | 5408 | SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), |
| 5409 | SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), | 5409 | SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), |
| 5410 | SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), | ||
| 5410 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), | 5411 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), |
| 5411 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), | 5412 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), |
| 5412 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), | 5413 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), |
| @@ -5840,7 +5841,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
| 5840 | return alc_parse_auto_config(codec, alc269_ignore, ssids); | 5841 | return alc_parse_auto_config(codec, alc269_ignore, ssids); |
| 5841 | } | 5842 | } |
| 5842 | 5843 | ||
| 5843 | static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) | 5844 | static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) |
| 5844 | { | 5845 | { |
| 5845 | int val = alc_read_coef_idx(codec, 0x04); | 5846 | int val = alc_read_coef_idx(codec, 0x04); |
| 5846 | if (power_up) | 5847 | if (power_up) |
| @@ -5857,10 +5858,10 @@ static void alc269_shutup(struct hda_codec *codec) | |||
| 5857 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) | 5858 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) |
| 5858 | return; | 5859 | return; |
| 5859 | 5860 | ||
| 5860 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) | 5861 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
| 5861 | alc269_toggle_power_output(codec, 0); | 5862 | alc269vb_toggle_power_output(codec, 0); |
| 5862 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { | 5863 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && |
| 5863 | alc269_toggle_power_output(codec, 0); | 5864 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { |
| 5864 | msleep(150); | 5865 | msleep(150); |
| 5865 | } | 5866 | } |
| 5866 | } | 5867 | } |
| @@ -5870,24 +5871,22 @@ static int alc269_resume(struct hda_codec *codec) | |||
| 5870 | { | 5871 | { |
| 5871 | struct alc_spec *spec = codec->spec; | 5872 | struct alc_spec *spec = codec->spec; |
| 5872 | 5873 | ||
| 5873 | if (spec->codec_variant == ALC269_TYPE_ALC269VB || | 5874 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
| 5875 | alc269vb_toggle_power_output(codec, 0); | ||
| 5876 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && | ||
| 5874 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { | 5877 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { |
| 5875 | alc269_toggle_power_output(codec, 0); | ||
| 5876 | msleep(150); | 5878 | msleep(150); |
| 5877 | } | 5879 | } |
| 5878 | 5880 | ||
| 5879 | codec->patch_ops.init(codec); | 5881 | codec->patch_ops.init(codec); |
| 5880 | 5882 | ||
| 5881 | if (spec->codec_variant == ALC269_TYPE_ALC269VB || | 5883 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
| 5884 | alc269vb_toggle_power_output(codec, 1); | ||
| 5885 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && | ||
| 5882 | (alc_get_coef0(codec) & 0x00ff) == 0x017) { | 5886 | (alc_get_coef0(codec) & 0x00ff) == 0x017) { |
| 5883 | alc269_toggle_power_output(codec, 1); | ||
| 5884 | msleep(200); | 5887 | msleep(200); |
| 5885 | } | 5888 | } |
| 5886 | 5889 | ||
| 5887 | if (spec->codec_variant == ALC269_TYPE_ALC269VB || | ||
| 5888 | (alc_get_coef0(codec) & 0x00ff) == 0x018) | ||
| 5889 | alc269_toggle_power_output(codec, 1); | ||
| 5890 | |||
| 5891 | snd_hda_codec_resume_amp(codec); | 5890 | snd_hda_codec_resume_amp(codec); |
| 5892 | snd_hda_codec_resume_cache(codec); | 5891 | snd_hda_codec_resume_cache(codec); |
| 5893 | hda_call_check_power_status(codec, 0x01); | 5892 | hda_call_check_power_status(codec, 0x01); |
| @@ -7079,6 +7078,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
| 7079 | .patch = patch_alc662 }, | 7078 | .patch = patch_alc662 }, |
| 7080 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, | 7079 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, |
| 7081 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, | 7080 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, |
| 7081 | { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, | ||
| 7082 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, | 7082 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, |
| 7083 | { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, | 7083 | { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, |
| 7084 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 7084 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
| @@ -7096,6 +7096,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
| 7096 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, | 7096 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, |
| 7097 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, | 7097 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, |
| 7098 | { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, | 7098 | { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, |
| 7099 | { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, | ||
| 7099 | {} /* terminator */ | 7100 | {} /* terminator */ |
| 7100 | }; | 7101 | }; |
| 7101 | 7102 | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 72a2f60b087c..019e1a00414a 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
| @@ -1809,11 +1809,11 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) | |||
| 1809 | { | 1809 | { |
| 1810 | struct via_spec *spec = codec->spec; | 1810 | struct via_spec *spec = codec->spec; |
| 1811 | const struct auto_pin_cfg *cfg = &spec->autocfg; | 1811 | const struct auto_pin_cfg *cfg = &spec->autocfg; |
| 1812 | int i, dac_num; | 1812 | int i; |
| 1813 | hda_nid_t nid; | 1813 | hda_nid_t nid; |
| 1814 | 1814 | ||
| 1815 | spec->multiout.num_dacs = 0; | ||
| 1815 | spec->multiout.dac_nids = spec->private_dac_nids; | 1816 | spec->multiout.dac_nids = spec->private_dac_nids; |
| 1816 | dac_num = 0; | ||
| 1817 | for (i = 0; i < cfg->line_outs; i++) { | 1817 | for (i = 0; i < cfg->line_outs; i++) { |
| 1818 | hda_nid_t dac = 0; | 1818 | hda_nid_t dac = 0; |
| 1819 | nid = cfg->line_out_pins[i]; | 1819 | nid = cfg->line_out_pins[i]; |
| @@ -1824,16 +1824,13 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) | |||
| 1824 | if (!i && parse_output_path(codec, nid, dac, 1, | 1824 | if (!i && parse_output_path(codec, nid, dac, 1, |
| 1825 | &spec->out_mix_path)) | 1825 | &spec->out_mix_path)) |
| 1826 | dac = spec->out_mix_path.path[0]; | 1826 | dac = spec->out_mix_path.path[0]; |
| 1827 | if (dac) { | 1827 | if (dac) |
| 1828 | spec->private_dac_nids[i] = dac; | 1828 | spec->private_dac_nids[spec->multiout.num_dacs++] = dac; |
| 1829 | dac_num++; | ||
| 1830 | } | ||
| 1831 | } | 1829 | } |
| 1832 | if (!spec->out_path[0].depth && spec->out_mix_path.depth) { | 1830 | if (!spec->out_path[0].depth && spec->out_mix_path.depth) { |
| 1833 | spec->out_path[0] = spec->out_mix_path; | 1831 | spec->out_path[0] = spec->out_mix_path; |
| 1834 | spec->out_mix_path.depth = 0; | 1832 | spec->out_mix_path.depth = 0; |
| 1835 | } | 1833 | } |
| 1836 | spec->multiout.num_dacs = dac_num; | ||
| 1837 | return 0; | 1834 | return 0; |
| 1838 | } | 1835 | } |
| 1839 | 1836 | ||
| @@ -3628,6 +3625,7 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) | |||
| 3628 | */ | 3625 | */ |
| 3629 | enum { | 3626 | enum { |
| 3630 | VIA_FIXUP_INTMIC_BOOST, | 3627 | VIA_FIXUP_INTMIC_BOOST, |
| 3628 | VIA_FIXUP_ASUS_G75, | ||
| 3631 | }; | 3629 | }; |
| 3632 | 3630 | ||
| 3633 | static void via_fixup_intmic_boost(struct hda_codec *codec, | 3631 | static void via_fixup_intmic_boost(struct hda_codec *codec, |
| @@ -3642,13 +3640,35 @@ static const struct hda_fixup via_fixups[] = { | |||
| 3642 | .type = HDA_FIXUP_FUNC, | 3640 | .type = HDA_FIXUP_FUNC, |
| 3643 | .v.func = via_fixup_intmic_boost, | 3641 | .v.func = via_fixup_intmic_boost, |
| 3644 | }, | 3642 | }, |
| 3643 | [VIA_FIXUP_ASUS_G75] = { | ||
| 3644 | .type = HDA_FIXUP_PINS, | ||
| 3645 | .v.pins = (const struct hda_pintbl[]) { | ||
| 3646 | /* set 0x24 and 0x33 as speakers */ | ||
| 3647 | { 0x24, 0x991301f0 }, | ||
| 3648 | { 0x33, 0x991301f1 }, /* subwoofer */ | ||
| 3649 | { } | ||
| 3650 | } | ||
| 3651 | }, | ||
| 3645 | }; | 3652 | }; |
| 3646 | 3653 | ||
| 3647 | static const struct snd_pci_quirk vt2002p_fixups[] = { | 3654 | static const struct snd_pci_quirk vt2002p_fixups[] = { |
| 3655 | SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75), | ||
| 3648 | SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST), | 3656 | SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST), |
| 3649 | {} | 3657 | {} |
| 3650 | }; | 3658 | }; |
| 3651 | 3659 | ||
| 3660 | /* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e | ||
| 3661 | * Replace this with mixer NID 0x1c | ||
| 3662 | */ | ||
| 3663 | static void fix_vt1802_connections(struct hda_codec *codec) | ||
| 3664 | { | ||
| 3665 | static hda_nid_t conn_24[] = { 0x14, 0x1c }; | ||
| 3666 | static hda_nid_t conn_33[] = { 0x1c }; | ||
| 3667 | |||
| 3668 | snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24); | ||
| 3669 | snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33); | ||
| 3670 | } | ||
| 3671 | |||
| 3652 | /* patch for vt2002P */ | 3672 | /* patch for vt2002P */ |
| 3653 | static int patch_vt2002P(struct hda_codec *codec) | 3673 | static int patch_vt2002P(struct hda_codec *codec) |
| 3654 | { | 3674 | { |
| @@ -3663,6 +3683,8 @@ static int patch_vt2002P(struct hda_codec *codec) | |||
| 3663 | spec->aa_mix_nid = 0x21; | 3683 | spec->aa_mix_nid = 0x21; |
| 3664 | override_mic_boost(codec, 0x2b, 0, 3, 40); | 3684 | override_mic_boost(codec, 0x2b, 0, 3, 40); |
| 3665 | override_mic_boost(codec, 0x29, 0, 3, 40); | 3685 | override_mic_boost(codec, 0x29, 0, 3, 40); |
| 3686 | if (spec->codec_type == VT1802) | ||
| 3687 | fix_vt1802_connections(codec); | ||
| 3666 | add_secret_dac_path(codec); | 3688 | add_secret_dac_path(codec); |
| 3667 | 3689 | ||
| 3668 | snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups); | 3690 | snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups); |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index f1cd1e387801..748e36c66603 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
| @@ -3979,7 +3979,8 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, | |||
| 3979 | case 8: /* SYNC IN */ | 3979 | case 8: /* SYNC IN */ |
| 3980 | val = hdspm_sync_in_sync_check(hdspm); break; | 3980 | val = hdspm_sync_in_sync_check(hdspm); break; |
| 3981 | default: | 3981 | default: |
| 3982 | val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1); | 3982 | val = hdspm_s1_sync_check(hdspm, |
| 3983 | kcontrol->private_value-1); | ||
| 3983 | } | 3984 | } |
| 3984 | break; | 3985 | break; |
| 3985 | 3986 | ||
| @@ -4899,7 +4900,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, | |||
| 4899 | insel = "Coaxial"; | 4900 | insel = "Coaxial"; |
| 4900 | break; | 4901 | break; |
| 4901 | default: | 4902 | default: |
| 4902 | insel = "Unkown"; | 4903 | insel = "Unknown"; |
| 4903 | } | 4904 | } |
| 4904 | 4905 | ||
| 4905 | snd_iprintf(buffer, | 4906 | snd_iprintf(buffer, |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 61599298fb26..97a81051e88d 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
| @@ -763,7 +763,7 @@ static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai, | |||
| 763 | if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) { | 763 | if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) { |
| 764 | cs42l52->sysclk = freq; | 764 | cs42l52->sysclk = freq; |
| 765 | } else { | 765 | } else { |
| 766 | dev_err(codec->dev, "Invalid freq paramter\n"); | 766 | dev_err(codec->dev, "Invalid freq parameter\n"); |
| 767 | return -EINVAL; | 767 | return -EINVAL; |
| 768 | } | 768 | } |
| 769 | return 0; | 769 | return 0; |
| @@ -773,7 +773,6 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
| 773 | { | 773 | { |
| 774 | struct snd_soc_codec *codec = codec_dai->codec; | 774 | struct snd_soc_codec *codec = codec_dai->codec; |
| 775 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); | 775 | struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); |
| 776 | int ret = 0; | ||
| 777 | u8 iface = 0; | 776 | u8 iface = 0; |
| 778 | 777 | ||
| 779 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 778 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
| @@ -822,7 +821,7 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
| 822 | case SND_SOC_DAIFMT_NB_IF: | 821 | case SND_SOC_DAIFMT_NB_IF: |
| 823 | break; | 822 | break; |
| 824 | default: | 823 | default: |
| 825 | ret = -EINVAL; | 824 | return -EINVAL; |
| 826 | } | 825 | } |
| 827 | cs42l52->config.format = iface; | 826 | cs42l52->config.format = iface; |
| 828 | snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format); | 827 | snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format); |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 1722b586bdba..7394e73fa43c 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
| @@ -42,6 +42,556 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | |||
| 42 | static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); | 42 | static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); |
| 43 | static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); | 43 | static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); |
| 44 | 44 | ||
| 45 | static const struct reg_default wm5102_sysclk_reva_patch[] = { | ||
| 46 | { 0x3000, 0x2225 }, | ||
| 47 | { 0x3001, 0x3a03 }, | ||
| 48 | { 0x3002, 0x0225 }, | ||
| 49 | { 0x3003, 0x0801 }, | ||
| 50 | { 0x3004, 0x6249 }, | ||
| 51 | { 0x3005, 0x0c04 }, | ||
| 52 | { 0x3006, 0x0225 }, | ||
| 53 | { 0x3007, 0x5901 }, | ||
| 54 | { 0x3008, 0xe249 }, | ||
| 55 | { 0x3009, 0x030d }, | ||
| 56 | { 0x300a, 0x0249 }, | ||
| 57 | { 0x300b, 0x2c01 }, | ||
| 58 | { 0x300c, 0xe249 }, | ||
| 59 | { 0x300d, 0x4342 }, | ||
| 60 | { 0x300e, 0xe249 }, | ||
| 61 | { 0x300f, 0x73c0 }, | ||
| 62 | { 0x3010, 0x4249 }, | ||
| 63 | { 0x3011, 0x0c00 }, | ||
| 64 | { 0x3012, 0x0225 }, | ||
| 65 | { 0x3013, 0x1f01 }, | ||
| 66 | { 0x3014, 0x0225 }, | ||
| 67 | { 0x3015, 0x1e01 }, | ||
| 68 | { 0x3016, 0x0225 }, | ||
| 69 | { 0x3017, 0xfa00 }, | ||
| 70 | { 0x3018, 0x0000 }, | ||
| 71 | { 0x3019, 0xf000 }, | ||
| 72 | { 0x301a, 0x0000 }, | ||
| 73 | { 0x301b, 0xf000 }, | ||
| 74 | { 0x301c, 0x0000 }, | ||
| 75 | { 0x301d, 0xf000 }, | ||
| 76 | { 0x301e, 0x0000 }, | ||
| 77 | { 0x301f, 0xf000 }, | ||
| 78 | { 0x3020, 0x0000 }, | ||
| 79 | { 0x3021, 0xf000 }, | ||
| 80 | { 0x3022, 0x0000 }, | ||
| 81 | { 0x3023, 0xf000 }, | ||
| 82 | { 0x3024, 0x0000 }, | ||
| 83 | { 0x3025, 0xf000 }, | ||
| 84 | { 0x3026, 0x0000 }, | ||
| 85 | { 0x3027, 0xf000 }, | ||
| 86 | { 0x3028, 0x0000 }, | ||
| 87 | { 0x3029, 0xf000 }, | ||
| 88 | { 0x302a, 0x0000 }, | ||
| 89 | { 0x302b, 0xf000 }, | ||
| 90 | { 0x302c, 0x0000 }, | ||
| 91 | { 0x302d, 0xf000 }, | ||
| 92 | { 0x302e, 0x0000 }, | ||
| 93 | { 0x302f, 0xf000 }, | ||
| 94 | { 0x3030, 0x0225 }, | ||
| 95 | { 0x3031, 0x1a01 }, | ||
| 96 | { 0x3032, 0x0225 }, | ||
| 97 | { 0x3033, 0x1e00 }, | ||
| 98 | { 0x3034, 0x0225 }, | ||
| 99 | { 0x3035, 0x1f00 }, | ||
| 100 | { 0x3036, 0x6225 }, | ||
| 101 | { 0x3037, 0xf800 }, | ||
| 102 | { 0x3038, 0x0000 }, | ||
| 103 | { 0x3039, 0xf000 }, | ||
| 104 | { 0x303a, 0x0000 }, | ||
| 105 | { 0x303b, 0xf000 }, | ||
| 106 | { 0x303c, 0x0000 }, | ||
| 107 | { 0x303d, 0xf000 }, | ||
| 108 | { 0x303e, 0x0000 }, | ||
| 109 | { 0x303f, 0xf000 }, | ||
| 110 | { 0x3040, 0x2226 }, | ||
| 111 | { 0x3041, 0x3a03 }, | ||
| 112 | { 0x3042, 0x0226 }, | ||
| 113 | { 0x3043, 0x0801 }, | ||
| 114 | { 0x3044, 0x6249 }, | ||
| 115 | { 0x3045, 0x0c06 }, | ||
| 116 | { 0x3046, 0x0226 }, | ||
| 117 | { 0x3047, 0x5901 }, | ||
| 118 | { 0x3048, 0xe249 }, | ||
| 119 | { 0x3049, 0x030d }, | ||
| 120 | { 0x304a, 0x0249 }, | ||
| 121 | { 0x304b, 0x2c01 }, | ||
| 122 | { 0x304c, 0xe249 }, | ||
| 123 | { 0x304d, 0x4342 }, | ||
| 124 | { 0x304e, 0xe249 }, | ||
| 125 | { 0x304f, 0x73c0 }, | ||
| 126 | { 0x3050, 0x4249 }, | ||
| 127 | { 0x3051, 0x0c00 }, | ||
| 128 | { 0x3052, 0x0226 }, | ||
| 129 | { 0x3053, 0x1f01 }, | ||
| 130 | { 0x3054, 0x0226 }, | ||
| 131 | { 0x3055, 0x1e01 }, | ||
| 132 | { 0x3056, 0x0226 }, | ||
| 133 | { 0x3057, 0xfa00 }, | ||
| 134 | { 0x3058, 0x0000 }, | ||
| 135 | { 0x3059, 0xf000 }, | ||
| 136 | { 0x305a, 0x0000 }, | ||
| 137 | { 0x305b, 0xf000 }, | ||
| 138 | { 0x305c, 0x0000 }, | ||
| 139 | { 0x305d, 0xf000 }, | ||
| 140 | { 0x305e, 0x0000 }, | ||
| 141 | { 0x305f, 0xf000 }, | ||
| 142 | { 0x3060, 0x0000 }, | ||
| 143 | { 0x3061, 0xf000 }, | ||
| 144 | { 0x3062, 0x0000 }, | ||
| 145 | { 0x3063, 0xf000 }, | ||
| 146 | { 0x3064, 0x0000 }, | ||
| 147 | { 0x3065, 0xf000 }, | ||
| 148 | { 0x3066, 0x0000 }, | ||
| 149 | { 0x3067, 0xf000 }, | ||
| 150 | { 0x3068, 0x0000 }, | ||
| 151 | { 0x3069, 0xf000 }, | ||
| 152 | { 0x306a, 0x0000 }, | ||
| 153 | { 0x306b, 0xf000 }, | ||
| 154 | { 0x306c, 0x0000 }, | ||
| 155 | { 0x306d, 0xf000 }, | ||
| 156 | { 0x306e, 0x0000 }, | ||
| 157 | { 0x306f, 0xf000 }, | ||
| 158 | { 0x3070, 0x0226 }, | ||
| 159 | { 0x3071, 0x1a01 }, | ||
| 160 | { 0x3072, 0x0226 }, | ||
| 161 | { 0x3073, 0x1e00 }, | ||
| 162 | { 0x3074, 0x0226 }, | ||
| 163 | { 0x3075, 0x1f00 }, | ||
| 164 | { 0x3076, 0x6226 }, | ||
| 165 | { 0x3077, 0xf800 }, | ||
| 166 | { 0x3078, 0x0000 }, | ||
| 167 | { 0x3079, 0xf000 }, | ||
| 168 | { 0x307a, 0x0000 }, | ||
| 169 | { 0x307b, 0xf000 }, | ||
| 170 | { 0x307c, 0x0000 }, | ||
| 171 | { 0x307d, 0xf000 }, | ||
| 172 | { 0x307e, 0x0000 }, | ||
| 173 | { 0x307f, 0xf000 }, | ||
| 174 | { 0x3080, 0x2227 }, | ||
| 175 | { 0x3081, 0x3a03 }, | ||
| 176 | { 0x3082, 0x0227 }, | ||
| 177 | { 0x3083, 0x0801 }, | ||
| 178 | { 0x3084, 0x6255 }, | ||
| 179 | { 0x3085, 0x0c04 }, | ||
| 180 | { 0x3086, 0x0227 }, | ||
| 181 | { 0x3087, 0x5901 }, | ||
| 182 | { 0x3088, 0xe255 }, | ||
| 183 | { 0x3089, 0x030d }, | ||
| 184 | { 0x308a, 0x0255 }, | ||
| 185 | { 0x308b, 0x2c01 }, | ||
| 186 | { 0x308c, 0xe255 }, | ||
| 187 | { 0x308d, 0x4342 }, | ||
| 188 | { 0x308e, 0xe255 }, | ||
| 189 | { 0x308f, 0x73c0 }, | ||
| 190 | { 0x3090, 0x4255 }, | ||
| 191 | { 0x3091, 0x0c00 }, | ||
| 192 | { 0x3092, 0x0227 }, | ||
| 193 | { 0x3093, 0x1f01 }, | ||
| 194 | { 0x3094, 0x0227 }, | ||
| 195 | { 0x3095, 0x1e01 }, | ||
| 196 | { 0x3096, 0x0227 }, | ||
| 197 | { 0x3097, 0xfa00 }, | ||
| 198 | { 0x3098, 0x0000 }, | ||
| 199 | { 0x3099, 0xf000 }, | ||
| 200 | { 0x309a, 0x0000 }, | ||
| 201 | { 0x309b, 0xf000 }, | ||
| 202 | { 0x309c, 0x0000 }, | ||
| 203 | { 0x309d, 0xf000 }, | ||
| 204 | { 0x309e, 0x0000 }, | ||
| 205 | { 0x309f, 0xf000 }, | ||
| 206 | { 0x30a0, 0x0000 }, | ||
| 207 | { 0x30a1, 0xf000 }, | ||
| 208 | { 0x30a2, 0x0000 }, | ||
| 209 | { 0x30a3, 0xf000 }, | ||
| 210 | { 0x30a4, 0x0000 }, | ||
| 211 | { 0x30a5, 0xf000 }, | ||
| 212 | { 0x30a6, 0x0000 }, | ||
| 213 | { 0x30a7, 0xf000 }, | ||
| 214 | { 0x30a8, 0x0000 }, | ||
| 215 | { 0x30a9, 0xf000 }, | ||
| 216 | { 0x30aa, 0x0000 }, | ||
| 217 | { 0x30ab, 0xf000 }, | ||
| 218 | { 0x30ac, 0x0000 }, | ||
| 219 | { 0x30ad, 0xf000 }, | ||
| 220 | { 0x30ae, 0x0000 }, | ||
| 221 | { 0x30af, 0xf000 }, | ||
| 222 | { 0x30b0, 0x0227 }, | ||
| 223 | { 0x30b1, 0x1a01 }, | ||
| 224 | { 0x30b2, 0x0227 }, | ||
| 225 | { 0x30b3, 0x1e00 }, | ||
| 226 | { 0x30b4, 0x0227 }, | ||
| 227 | { 0x30b5, 0x1f00 }, | ||
| 228 | { 0x30b6, 0x6227 }, | ||
| 229 | { 0x30b7, 0xf800 }, | ||
| 230 | { 0x30b8, 0x0000 }, | ||
| 231 | { 0x30b9, 0xf000 }, | ||
| 232 | { 0x30ba, 0x0000 }, | ||
| 233 | { 0x30bb, 0xf000 }, | ||
| 234 | { 0x30bc, 0x0000 }, | ||
| 235 | { 0x30bd, 0xf000 }, | ||
| 236 | { 0x30be, 0x0000 }, | ||
| 237 | { 0x30bf, 0xf000 }, | ||
| 238 | { 0x30c0, 0x2228 }, | ||
| 239 | { 0x30c1, 0x3a03 }, | ||
| 240 | { 0x30c2, 0x0228 }, | ||
| 241 | { 0x30c3, 0x0801 }, | ||
| 242 | { 0x30c4, 0x6255 }, | ||
| 243 | { 0x30c5, 0x0c06 }, | ||
| 244 | { 0x30c6, 0x0228 }, | ||
| 245 | { 0x30c7, 0x5901 }, | ||
| 246 | { 0x30c8, 0xe255 }, | ||
| 247 | { 0x30c9, 0x030d }, | ||
| 248 | { 0x30ca, 0x0255 }, | ||
| 249 | { 0x30cb, 0x2c01 }, | ||
| 250 | { 0x30cc, 0xe255 }, | ||
| 251 | { 0x30cd, 0x4342 }, | ||
| 252 | { 0x30ce, 0xe255 }, | ||
| 253 | { 0x30cf, 0x73c0 }, | ||
| 254 | { 0x30d0, 0x4255 }, | ||
| 255 | { 0x30d1, 0x0c00 }, | ||
| 256 | { 0x30d2, 0x0228 }, | ||
| 257 | { 0x30d3, 0x1f01 }, | ||
| 258 | { 0x30d4, 0x0228 }, | ||
| 259 | { 0x30d5, 0x1e01 }, | ||
| 260 | { 0x30d6, 0x0228 }, | ||
| 261 | { 0x30d7, 0xfa00 }, | ||
| 262 | { 0x30d8, 0x0000 }, | ||
| 263 | { 0x30d9, 0xf000 }, | ||
| 264 | { 0x30da, 0x0000 }, | ||
| 265 | { 0x30db, 0xf000 }, | ||
| 266 | { 0x30dc, 0x0000 }, | ||
| 267 | { 0x30dd, 0xf000 }, | ||
| 268 | { 0x30de, 0x0000 }, | ||
| 269 | { 0x30df, 0xf000 }, | ||
| 270 | { 0x30e0, 0x0000 }, | ||
| 271 | { 0x30e1, 0xf000 }, | ||
| 272 | { 0x30e2, 0x0000 }, | ||
| 273 | { 0x30e3, 0xf000 }, | ||
| 274 | { 0x30e4, 0x0000 }, | ||
| 275 | { 0x30e5, 0xf000 }, | ||
| 276 | { 0x30e6, 0x0000 }, | ||
| 277 | { 0x30e7, 0xf000 }, | ||
| 278 | { 0x30e8, 0x0000 }, | ||
| 279 | { 0x30e9, 0xf000 }, | ||
| 280 | { 0x30ea, 0x0000 }, | ||
| 281 | { 0x30eb, 0xf000 }, | ||
| 282 | { 0x30ec, 0x0000 }, | ||
| 283 | { 0x30ed, 0xf000 }, | ||
| 284 | { 0x30ee, 0x0000 }, | ||
| 285 | { 0x30ef, 0xf000 }, | ||
| 286 | { 0x30f0, 0x0228 }, | ||
| 287 | { 0x30f1, 0x1a01 }, | ||
| 288 | { 0x30f2, 0x0228 }, | ||
| 289 | { 0x30f3, 0x1e00 }, | ||
| 290 | { 0x30f4, 0x0228 }, | ||
| 291 | { 0x30f5, 0x1f00 }, | ||
| 292 | { 0x30f6, 0x6228 }, | ||
| 293 | { 0x30f7, 0xf800 }, | ||
| 294 | { 0x30f8, 0x0000 }, | ||
| 295 | { 0x30f9, 0xf000 }, | ||
| 296 | { 0x30fa, 0x0000 }, | ||
| 297 | { 0x30fb, 0xf000 }, | ||
| 298 | { 0x30fc, 0x0000 }, | ||
| 299 | { 0x30fd, 0xf000 }, | ||
| 300 | { 0x30fe, 0x0000 }, | ||
| 301 | { 0x30ff, 0xf000 }, | ||
| 302 | { 0x3100, 0x222b }, | ||
| 303 | { 0x3101, 0x3a03 }, | ||
| 304 | { 0x3102, 0x222b }, | ||
| 305 | { 0x3103, 0x5803 }, | ||
| 306 | { 0x3104, 0xe26f }, | ||
| 307 | { 0x3105, 0x030d }, | ||
| 308 | { 0x3106, 0x626f }, | ||
| 309 | { 0x3107, 0x2c01 }, | ||
| 310 | { 0x3108, 0xe26f }, | ||
| 311 | { 0x3109, 0x4342 }, | ||
| 312 | { 0x310a, 0xe26f }, | ||
| 313 | { 0x310b, 0x73c0 }, | ||
| 314 | { 0x310c, 0x026f }, | ||
| 315 | { 0x310d, 0x0c00 }, | ||
| 316 | { 0x310e, 0x022b }, | ||
| 317 | { 0x310f, 0x1f01 }, | ||
| 318 | { 0x3110, 0x022b }, | ||
| 319 | { 0x3111, 0x1e01 }, | ||
| 320 | { 0x3112, 0x022b }, | ||
| 321 | { 0x3113, 0xfa00 }, | ||
| 322 | { 0x3114, 0x0000 }, | ||
| 323 | { 0x3115, 0xf000 }, | ||
| 324 | { 0x3116, 0x0000 }, | ||
| 325 | { 0x3117, 0xf000 }, | ||
| 326 | { 0x3118, 0x0000 }, | ||
| 327 | { 0x3119, 0xf000 }, | ||
| 328 | { 0x311a, 0x0000 }, | ||
| 329 | { 0x311b, 0xf000 }, | ||
| 330 | { 0x311c, 0x0000 }, | ||
| 331 | { 0x311d, 0xf000 }, | ||
| 332 | { 0x311e, 0x0000 }, | ||
| 333 | { 0x311f, 0xf000 }, | ||
| 334 | { 0x3120, 0x022b }, | ||
| 335 | { 0x3121, 0x0a01 }, | ||
| 336 | { 0x3122, 0x022b }, | ||
| 337 | { 0x3123, 0x1e00 }, | ||
| 338 | { 0x3124, 0x022b }, | ||
| 339 | { 0x3125, 0x1f00 }, | ||
| 340 | { 0x3126, 0x622b }, | ||
| 341 | { 0x3127, 0xf800 }, | ||
| 342 | { 0x3128, 0x0000 }, | ||
| 343 | { 0x3129, 0xf000 }, | ||
| 344 | { 0x312a, 0x0000 }, | ||
| 345 | { 0x312b, 0xf000 }, | ||
| 346 | { 0x312c, 0x0000 }, | ||
| 347 | { 0x312d, 0xf000 }, | ||
| 348 | { 0x312e, 0x0000 }, | ||
| 349 | { 0x312f, 0xf000 }, | ||
| 350 | { 0x3130, 0x0000 }, | ||
| 351 | { 0x3131, 0xf000 }, | ||
| 352 | { 0x3132, 0x0000 }, | ||
| 353 | { 0x3133, 0xf000 }, | ||
| 354 | { 0x3134, 0x0000 }, | ||
| 355 | { 0x3135, 0xf000 }, | ||
| 356 | { 0x3136, 0x0000 }, | ||
| 357 | { 0x3137, 0xf000 }, | ||
| 358 | { 0x3138, 0x0000 }, | ||
| 359 | { 0x3139, 0xf000 }, | ||
| 360 | { 0x313a, 0x0000 }, | ||
| 361 | { 0x313b, 0xf000 }, | ||
| 362 | { 0x313c, 0x0000 }, | ||
| 363 | { 0x313d, 0xf000 }, | ||
| 364 | { 0x313e, 0x0000 }, | ||
| 365 | { 0x313f, 0xf000 }, | ||
| 366 | { 0x3140, 0x0000 }, | ||
| 367 | { 0x3141, 0xf000 }, | ||
| 368 | { 0x3142, 0x0000 }, | ||
| 369 | { 0x3143, 0xf000 }, | ||
| 370 | { 0x3144, 0x0000 }, | ||
| 371 | { 0x3145, 0xf000 }, | ||
| 372 | { 0x3146, 0x0000 }, | ||
| 373 | { 0x3147, 0xf000 }, | ||
| 374 | { 0x3148, 0x0000 }, | ||
| 375 | { 0x3149, 0xf000 }, | ||
| 376 | { 0x314a, 0x0000 }, | ||
| 377 | { 0x314b, 0xf000 }, | ||
| 378 | { 0x314c, 0x0000 }, | ||
| 379 | { 0x314d, 0xf000 }, | ||
| 380 | { 0x314e, 0x0000 }, | ||
| 381 | { 0x314f, 0xf000 }, | ||
| 382 | { 0x3150, 0x0000 }, | ||
| 383 | { 0x3151, 0xf000 }, | ||
| 384 | { 0x3152, 0x0000 }, | ||
| 385 | { 0x3153, 0xf000 }, | ||
| 386 | { 0x3154, 0x0000 }, | ||
| 387 | { 0x3155, 0xf000 }, | ||
| 388 | { 0x3156, 0x0000 }, | ||
| 389 | { 0x3157, 0xf000 }, | ||
| 390 | { 0x3158, 0x0000 }, | ||
| 391 | { 0x3159, 0xf000 }, | ||
| 392 | { 0x315a, 0x0000 }, | ||
| 393 | { 0x315b, 0xf000 }, | ||
| 394 | { 0x315c, 0x0000 }, | ||
| 395 | { 0x315d, 0xf000 }, | ||
| 396 | { 0x315e, 0x0000 }, | ||
| 397 | { 0x315f, 0xf000 }, | ||
| 398 | { 0x3160, 0x0000 }, | ||
| 399 | { 0x3161, 0xf000 }, | ||
| 400 | { 0x3162, 0x0000 }, | ||
| 401 | { 0x3163, 0xf000 }, | ||
| 402 | { 0x3164, 0x0000 }, | ||
| 403 | { 0x3165, 0xf000 }, | ||
| 404 | { 0x3166, 0x0000 }, | ||
| 405 | { 0x3167, 0xf000 }, | ||
| 406 | { 0x3168, 0x0000 }, | ||
| 407 | { 0x3169, 0xf000 }, | ||
| 408 | { 0x316a, 0x0000 }, | ||
| 409 | { 0x316b, 0xf000 }, | ||
| 410 | { 0x316c, 0x0000 }, | ||
| 411 | { 0x316d, 0xf000 }, | ||
| 412 | { 0x316e, 0x0000 }, | ||
| 413 | { 0x316f, 0xf000 }, | ||
| 414 | { 0x3170, 0x0000 }, | ||
| 415 | { 0x3171, 0xf000 }, | ||
| 416 | { 0x3172, 0x0000 }, | ||
| 417 | { 0x3173, 0xf000 }, | ||
| 418 | { 0x3174, 0x0000 }, | ||
| 419 | { 0x3175, 0xf000 }, | ||
| 420 | { 0x3176, 0x0000 }, | ||
| 421 | { 0x3177, 0xf000 }, | ||
| 422 | { 0x3178, 0x0000 }, | ||
| 423 | { 0x3179, 0xf000 }, | ||
| 424 | { 0x317a, 0x0000 }, | ||
| 425 | { 0x317b, 0xf000 }, | ||
| 426 | { 0x317c, 0x0000 }, | ||
| 427 | { 0x317d, 0xf000 }, | ||
| 428 | { 0x317e, 0x0000 }, | ||
| 429 | { 0x317f, 0xf000 }, | ||
| 430 | { 0x3180, 0x2001 }, | ||
| 431 | { 0x3181, 0xf101 }, | ||
| 432 | { 0x3182, 0x0000 }, | ||
| 433 | { 0x3183, 0xf000 }, | ||
| 434 | { 0x3184, 0x0000 }, | ||
| 435 | { 0x3185, 0xf000 }, | ||
| 436 | { 0x3186, 0x0000 }, | ||
| 437 | { 0x3187, 0xf000 }, | ||
| 438 | { 0x3188, 0x0000 }, | ||
| 439 | { 0x3189, 0xf000 }, | ||
| 440 | { 0x318a, 0x0000 }, | ||
| 441 | { 0x318b, 0xf000 }, | ||
| 442 | { 0x318c, 0x0000 }, | ||
| 443 | { 0x318d, 0xf000 }, | ||
| 444 | { 0x318e, 0x0000 }, | ||
| 445 | { 0x318f, 0xf000 }, | ||
| 446 | { 0x3190, 0x0000 }, | ||
| 447 | { 0x3191, 0xf000 }, | ||
| 448 | { 0x3192, 0x0000 }, | ||
| 449 | { 0x3193, 0xf000 }, | ||
| 450 | { 0x3194, 0x0000 }, | ||
| 451 | { 0x3195, 0xf000 }, | ||
| 452 | { 0x3196, 0x0000 }, | ||
| 453 | { 0x3197, 0xf000 }, | ||
| 454 | { 0x3198, 0x0000 }, | ||
| 455 | { 0x3199, 0xf000 }, | ||
| 456 | { 0x319a, 0x0000 }, | ||
| 457 | { 0x319b, 0xf000 }, | ||
| 458 | { 0x319c, 0x0000 }, | ||
| 459 | { 0x319d, 0xf000 }, | ||
| 460 | { 0x319e, 0x0000 }, | ||
| 461 | { 0x319f, 0xf000 }, | ||
| 462 | { 0x31a0, 0x0000 }, | ||
| 463 | { 0x31a1, 0xf000 }, | ||
| 464 | { 0x31a2, 0x0000 }, | ||
| 465 | { 0x31a3, 0xf000 }, | ||
| 466 | { 0x31a4, 0x0000 }, | ||
| 467 | { 0x31a5, 0xf000 }, | ||
| 468 | { 0x31a6, 0x0000 }, | ||
| 469 | { 0x31a7, 0xf000 }, | ||
| 470 | { 0x31a8, 0x0000 }, | ||
| 471 | { 0x31a9, 0xf000 }, | ||
| 472 | { 0x31aa, 0x0000 }, | ||
| 473 | { 0x31ab, 0xf000 }, | ||
| 474 | { 0x31ac, 0x0000 }, | ||
| 475 | { 0x31ad, 0xf000 }, | ||
| 476 | { 0x31ae, 0x0000 }, | ||
| 477 | { 0x31af, 0xf000 }, | ||
| 478 | { 0x31b0, 0x0000 }, | ||
| 479 | { 0x31b1, 0xf000 }, | ||
| 480 | { 0x31b2, 0x0000 }, | ||
| 481 | { 0x31b3, 0xf000 }, | ||
| 482 | { 0x31b4, 0x0000 }, | ||
| 483 | { 0x31b5, 0xf000 }, | ||
| 484 | { 0x31b6, 0x0000 }, | ||
| 485 | { 0x31b7, 0xf000 }, | ||
| 486 | { 0x31b8, 0x0000 }, | ||
| 487 | { 0x31b9, 0xf000 }, | ||
| 488 | { 0x31ba, 0x0000 }, | ||
| 489 | { 0x31bb, 0xf000 }, | ||
| 490 | { 0x31bc, 0x0000 }, | ||
| 491 | { 0x31bd, 0xf000 }, | ||
| 492 | { 0x31be, 0x0000 }, | ||
| 493 | { 0x31bf, 0xf000 }, | ||
| 494 | { 0x31c0, 0x0000 }, | ||
| 495 | { 0x31c1, 0xf000 }, | ||
| 496 | { 0x31c2, 0x0000 }, | ||
| 497 | { 0x31c3, 0xf000 }, | ||
| 498 | { 0x31c4, 0x0000 }, | ||
| 499 | { 0x31c5, 0xf000 }, | ||
| 500 | { 0x31c6, 0x0000 }, | ||
| 501 | { 0x31c7, 0xf000 }, | ||
| 502 | { 0x31c8, 0x0000 }, | ||
| 503 | { 0x31c9, 0xf000 }, | ||
| 504 | { 0x31ca, 0x0000 }, | ||
| 505 | { 0x31cb, 0xf000 }, | ||
| 506 | { 0x31cc, 0x0000 }, | ||
| 507 | { 0x31cd, 0xf000 }, | ||
| 508 | { 0x31ce, 0x0000 }, | ||
| 509 | { 0x31cf, 0xf000 }, | ||
| 510 | { 0x31d0, 0x0000 }, | ||
| 511 | { 0x31d1, 0xf000 }, | ||
| 512 | { 0x31d2, 0x0000 }, | ||
| 513 | { 0x31d3, 0xf000 }, | ||
| 514 | { 0x31d4, 0x0000 }, | ||
| 515 | { 0x31d5, 0xf000 }, | ||
| 516 | { 0x31d6, 0x0000 }, | ||
| 517 | { 0x31d7, 0xf000 }, | ||
| 518 | { 0x31d8, 0x0000 }, | ||
| 519 | { 0x31d9, 0xf000 }, | ||
| 520 | { 0x31da, 0x0000 }, | ||
| 521 | { 0x31db, 0xf000 }, | ||
| 522 | { 0x31dc, 0x0000 }, | ||
| 523 | { 0x31dd, 0xf000 }, | ||
| 524 | { 0x31de, 0x0000 }, | ||
| 525 | { 0x31df, 0xf000 }, | ||
| 526 | { 0x31e0, 0x0000 }, | ||
| 527 | { 0x31e1, 0xf000 }, | ||
| 528 | { 0x31e2, 0x0000 }, | ||
| 529 | { 0x31e3, 0xf000 }, | ||
| 530 | { 0x31e4, 0x0000 }, | ||
| 531 | { 0x31e5, 0xf000 }, | ||
| 532 | { 0x31e6, 0x0000 }, | ||
| 533 | { 0x31e7, 0xf000 }, | ||
| 534 | { 0x31e8, 0x0000 }, | ||
| 535 | { 0x31e9, 0xf000 }, | ||
| 536 | { 0x31ea, 0x0000 }, | ||
| 537 | { 0x31eb, 0xf000 }, | ||
| 538 | { 0x31ec, 0x0000 }, | ||
| 539 | { 0x31ed, 0xf000 }, | ||
| 540 | { 0x31ee, 0x0000 }, | ||
| 541 | { 0x31ef, 0xf000 }, | ||
| 542 | { 0x31f0, 0x0000 }, | ||
| 543 | { 0x31f1, 0xf000 }, | ||
| 544 | { 0x31f2, 0x0000 }, | ||
| 545 | { 0x31f3, 0xf000 }, | ||
| 546 | { 0x31f4, 0x0000 }, | ||
| 547 | { 0x31f5, 0xf000 }, | ||
| 548 | { 0x31f6, 0x0000 }, | ||
| 549 | { 0x31f7, 0xf000 }, | ||
| 550 | { 0x31f8, 0x0000 }, | ||
| 551 | { 0x31f9, 0xf000 }, | ||
| 552 | { 0x31fa, 0x0000 }, | ||
| 553 | { 0x31fb, 0xf000 }, | ||
| 554 | { 0x31fc, 0x0000 }, | ||
| 555 | { 0x31fd, 0xf000 }, | ||
| 556 | { 0x31fe, 0x0000 }, | ||
| 557 | { 0x31ff, 0xf000 }, | ||
| 558 | { 0x024d, 0xff50 }, | ||
| 559 | { 0x0252, 0xff50 }, | ||
| 560 | { 0x0259, 0x0112 }, | ||
| 561 | { 0x025e, 0x0112 }, | ||
| 562 | }; | ||
| 563 | |||
| 564 | static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, | ||
| 565 | struct snd_kcontrol *kcontrol, int event) | ||
| 566 | { | ||
| 567 | struct snd_soc_codec *codec = w->codec; | ||
| 568 | struct arizona *arizona = dev_get_drvdata(codec->dev); | ||
| 569 | struct regmap *regmap = codec->control_data; | ||
| 570 | const struct reg_default *patch = NULL; | ||
| 571 | int i, patch_size; | ||
| 572 | |||
| 573 | switch (arizona->rev) { | ||
| 574 | case 0: | ||
| 575 | patch = wm5102_sysclk_reva_patch; | ||
| 576 | patch_size = ARRAY_SIZE(wm5102_sysclk_reva_patch); | ||
| 577 | break; | ||
| 578 | } | ||
| 579 | |||
| 580 | switch (event) { | ||
| 581 | case SND_SOC_DAPM_POST_PMU: | ||
| 582 | if (patch) | ||
| 583 | for (i = 0; i < patch_size; i++) | ||
| 584 | regmap_write(regmap, patch[i].reg, | ||
| 585 | patch[i].def); | ||
| 586 | break; | ||
| 587 | |||
| 588 | default: | ||
| 589 | break; | ||
| 590 | } | ||
| 591 | |||
| 592 | return 0; | ||
| 593 | } | ||
| 594 | |||
| 45 | static const struct snd_kcontrol_new wm5102_snd_controls[] = { | 595 | static const struct snd_kcontrol_new wm5102_snd_controls[] = { |
| 46 | SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL, | 596 | SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL, |
| 47 | ARIZONA_IN1_OSR_SHIFT, 1, 0), | 597 | ARIZONA_IN1_OSR_SHIFT, 1, 0), |
| @@ -297,7 +847,7 @@ static const struct snd_kcontrol_new wm5102_aec_loopback_mux = | |||
| 297 | 847 | ||
| 298 | static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { | 848 | static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { |
| 299 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, | 849 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, |
| 300 | 0, NULL, 0), | 850 | 0, wm5102_sysclk_ev, SND_SOC_DAPM_POST_PMU), |
| 301 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, | 851 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, |
| 302 | ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), | 852 | ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), |
| 303 | SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, | 853 | SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, |
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 5421fd9fbcb5..4c0a8e496131 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c | |||
| @@ -782,7 +782,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream, | |||
| 782 | wm8978->mclk_idx = -1; | 782 | wm8978->mclk_idx = -1; |
| 783 | f_sel = wm8978->f_mclk; | 783 | f_sel = wm8978->f_mclk; |
| 784 | } else { | 784 | } else { |
| 785 | if (!wm8978->f_pllout) { | 785 | if (!wm8978->f_opclk) { |
| 786 | /* We only enter here, if OPCLK is not used */ | 786 | /* We only enter here, if OPCLK is not used */ |
| 787 | int ret = wm8978_configure_pll(codec); | 787 | int ret = wm8978_configure_pll(codec); |
| 788 | if (ret < 0) | 788 | if (ret < 0) |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 3fddc7ad1127..b2b2b37131bd 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
| @@ -3722,7 +3722,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
| 3722 | } while (count--); | 3722 | } while (count--); |
| 3723 | 3723 | ||
| 3724 | if (count == 0) | 3724 | if (count == 0) |
| 3725 | dev_warn(codec->dev, "No impedence range reported for jack\n"); | 3725 | dev_warn(codec->dev, "No impedance range reported for jack\n"); |
| 3726 | 3726 | ||
| 3727 | #ifndef CONFIG_SND_SOC_WM8994_MODULE | 3727 | #ifndef CONFIG_SND_SOC_WM8994_MODULE |
| 3728 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | 3728 | trace_snd_soc_jack_irq(dev_name(codec->dev)); |
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index aa037b292f3d..c294fbb523fc 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c | |||
| @@ -523,16 +523,24 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, | |||
| 523 | 523 | ||
| 524 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 524 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 525 | /* | 525 | /* |
| 526 | * write a data to saif data register to trigger | 526 | * write data to saif data register to trigger |
| 527 | * the transfer | 527 | * the transfer. |
| 528 | * For 24-bit format the 32-bit FIFO register stores | ||
| 529 | * only one channel, so we need to write twice. | ||
| 530 | * This is also safe for the other non 24-bit formats. | ||
| 528 | */ | 531 | */ |
| 529 | __raw_writel(0, saif->base + SAIF_DATA); | 532 | __raw_writel(0, saif->base + SAIF_DATA); |
| 533 | __raw_writel(0, saif->base + SAIF_DATA); | ||
| 530 | } else { | 534 | } else { |
| 531 | /* | 535 | /* |
| 532 | * read a data from saif data register to trigger | 536 | * read data from saif data register to trigger |
| 533 | * the receive | 537 | * the receive. |
| 538 | * For 24-bit format the 32-bit FIFO register stores | ||
| 539 | * only one channel, so we need to read twice. | ||
| 540 | * This is also safe for the other non 24-bit formats. | ||
| 534 | */ | 541 | */ |
| 535 | __raw_readl(saif->base + SAIF_DATA); | 542 | __raw_readl(saif->base + SAIF_DATA); |
| 543 | __raw_readl(saif->base + SAIF_DATA); | ||
| 536 | } | 544 | } |
| 537 | 545 | ||
| 538 | master_saif->ongoing = 1; | 546 | master_saif->ongoing = 1; |
| @@ -812,3 +820,4 @@ module_platform_driver(mxs_saif_driver); | |||
| 812 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | 820 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); |
| 813 | MODULE_DESCRIPTION("MXS ASoC SAIF driver"); | 821 | MODULE_DESCRIPTION("MXS ASoC SAIF driver"); |
| 814 | MODULE_LICENSE("GPL"); | 822 | MODULE_LICENSE("GPL"); |
| 823 | MODULE_ALIAS("platform:mxs-saif"); | ||
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index e7b83179aca2..3c7c3a59ed39 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
| @@ -207,6 +207,8 @@ config SND_SOC_BELLS | |||
| 207 | select SND_SOC_WM5102 | 207 | select SND_SOC_WM5102 |
| 208 | select SND_SOC_WM5110 | 208 | select SND_SOC_WM5110 |
| 209 | select SND_SOC_WM9081 | 209 | select SND_SOC_WM9081 |
| 210 | select SND_SOC_WM0010 | ||
| 211 | select SND_SOC_WM1250_EV1 | ||
| 210 | 212 | ||
| 211 | config SND_SOC_LOWLAND | 213 | config SND_SOC_LOWLAND |
| 212 | tristate "Audio support for Wolfson Lowland" | 214 | tristate "Audio support for Wolfson Lowland" |
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index b0d46d63d55e..b56b9a3c6169 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c | |||
| @@ -247,7 +247,7 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = { | |||
| 247 | { | 247 | { |
| 248 | .name = "Sub", | 248 | .name = "Sub", |
| 249 | .stream_name = "Sub", | 249 | .stream_name = "Sub", |
| 250 | .cpu_dai_name = "wm5110-aif3", | 250 | .cpu_dai_name = "wm5102-aif3", |
| 251 | .codec_dai_name = "wm9081-hifi", | 251 | .codec_dai_name = "wm9081-hifi", |
| 252 | .codec_name = "wm9081.1-006c", | 252 | .codec_name = "wm9081.1-006c", |
| 253 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 253 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d1198627fc40..10d21be383f6 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
| @@ -2786,8 +2786,9 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, | |||
| 2786 | val = (ucontrol->value.integer.value[0] + min) & mask; | 2786 | val = (ucontrol->value.integer.value[0] + min) & mask; |
| 2787 | val = val << shift; | 2787 | val = val << shift; |
| 2788 | 2788 | ||
| 2789 | if (snd_soc_update_bits_locked(codec, reg, val_mask, val)) | 2789 | err = snd_soc_update_bits_locked(codec, reg, val_mask, val); |
| 2790 | return err; | 2790 | if (err < 0) |
| 2791 | return err; | ||
| 2791 | 2792 | ||
| 2792 | if (snd_soc_volsw_is_stereo(mc)) { | 2793 | if (snd_soc_volsw_is_stereo(mc)) { |
| 2793 | val_mask = mask << rshift; | 2794 | val_mask = mask << rshift; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d0a4be38dc0f..6e35bcae02df 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
| @@ -3745,7 +3745,7 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card) | |||
| 3745 | { | 3745 | { |
| 3746 | struct snd_soc_codec *codec; | 3746 | struct snd_soc_codec *codec; |
| 3747 | 3747 | ||
| 3748 | list_for_each_entry(codec, &card->codec_dev_list, list) { | 3748 | list_for_each_entry(codec, &card->codec_dev_list, card_list) { |
| 3749 | soc_dapm_shutdown_codec(&codec->dapm); | 3749 | soc_dapm_shutdown_codec(&codec->dapm); |
| 3750 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) | 3750 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) |
| 3751 | snd_soc_dapm_set_bias_level(&codec->dapm, | 3751 | snd_soc_dapm_set_bias_level(&codec->dapm, |
diff --git a/sound/usb/card.c b/sound/usb/card.c index 282f0fc9fed1..dbf7999d18b4 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
| @@ -559,9 +559,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, | |||
| 559 | return; | 559 | return; |
| 560 | 560 | ||
| 561 | card = chip->card; | 561 | card = chip->card; |
| 562 | mutex_lock(®ister_mutex); | ||
| 563 | down_write(&chip->shutdown_rwsem); | 562 | down_write(&chip->shutdown_rwsem); |
| 564 | chip->shutdown = 1; | 563 | chip->shutdown = 1; |
| 564 | up_write(&chip->shutdown_rwsem); | ||
| 565 | |||
| 566 | mutex_lock(®ister_mutex); | ||
| 565 | chip->num_interfaces--; | 567 | chip->num_interfaces--; |
| 566 | if (chip->num_interfaces <= 0) { | 568 | if (chip->num_interfaces <= 0) { |
| 567 | snd_card_disconnect(card); | 569 | snd_card_disconnect(card); |
| @@ -582,11 +584,9 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, | |||
| 582 | snd_usb_mixer_disconnect(p); | 584 | snd_usb_mixer_disconnect(p); |
| 583 | } | 585 | } |
| 584 | usb_chip[chip->index] = NULL; | 586 | usb_chip[chip->index] = NULL; |
| 585 | up_write(&chip->shutdown_rwsem); | ||
| 586 | mutex_unlock(®ister_mutex); | 587 | mutex_unlock(®ister_mutex); |
| 587 | snd_card_free_when_closed(card); | 588 | snd_card_free_when_closed(card); |
| 588 | } else { | 589 | } else { |
| 589 | up_write(&chip->shutdown_rwsem); | ||
| 590 | mutex_unlock(®ister_mutex); | 590 | mutex_unlock(®ister_mutex); |
| 591 | } | 591 | } |
| 592 | } | 592 | } |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 7f78c6d782b0..34de6f2faf61 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | 35 | ||
| 36 | #define EP_FLAG_ACTIVATED 0 | 36 | #define EP_FLAG_ACTIVATED 0 |
| 37 | #define EP_FLAG_RUNNING 1 | 37 | #define EP_FLAG_RUNNING 1 |
| 38 | #define EP_FLAG_STOPPING 2 | ||
| 38 | 39 | ||
| 39 | /* | 40 | /* |
| 40 | * snd_usb_endpoint is a model that abstracts everything related to an | 41 | * snd_usb_endpoint is a model that abstracts everything related to an |
| @@ -502,10 +503,20 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep) | |||
| 502 | if (alive) | 503 | if (alive) |
| 503 | snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n", | 504 | snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n", |
| 504 | alive, ep->ep_num); | 505 | alive, ep->ep_num); |
| 506 | clear_bit(EP_FLAG_STOPPING, &ep->flags); | ||
| 505 | 507 | ||
| 506 | return 0; | 508 | return 0; |
| 507 | } | 509 | } |
| 508 | 510 | ||
| 511 | /* sync the pending stop operation; | ||
| 512 | * this function itself doesn't trigger the stop operation | ||
| 513 | */ | ||
| 514 | void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep) | ||
| 515 | { | ||
| 516 | if (ep && test_bit(EP_FLAG_STOPPING, &ep->flags)) | ||
| 517 | wait_clear_urbs(ep); | ||
| 518 | } | ||
| 519 | |||
| 509 | /* | 520 | /* |
| 510 | * unlink active urbs. | 521 | * unlink active urbs. |
| 511 | */ | 522 | */ |
| @@ -918,6 +929,8 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, | |||
| 918 | 929 | ||
| 919 | if (wait) | 930 | if (wait) |
| 920 | wait_clear_urbs(ep); | 931 | wait_clear_urbs(ep); |
| 932 | else | ||
| 933 | set_bit(EP_FLAG_STOPPING, &ep->flags); | ||
| 921 | } | 934 | } |
| 922 | } | 935 | } |
| 923 | 936 | ||
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index 6376ccf10fd4..3d4c9705041f 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h | |||
| @@ -19,6 +19,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | |||
| 19 | int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep); | 19 | int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep); |
| 20 | void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, | 20 | void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, |
| 21 | int force, int can_sleep, int wait); | 21 | int force, int can_sleep, int wait); |
| 22 | void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); | ||
| 22 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); | 23 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); |
| 23 | int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); | 24 | int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); |
| 24 | void snd_usb_endpoint_free(struct list_head *head); | 25 | void snd_usb_endpoint_free(struct list_head *head); |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 37428f74dbb6..5c12a3fe8c3e 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
| @@ -568,6 +568,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) | |||
| 568 | goto unlock; | 568 | goto unlock; |
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint); | ||
| 572 | snd_usb_endpoint_sync_pending_stop(subs->data_endpoint); | ||
| 573 | |||
| 571 | ret = set_format(subs, subs->cur_audiofmt); | 574 | ret = set_format(subs, subs->cur_audiofmt); |
| 572 | if (ret < 0) | 575 | if (ret < 0) |
| 573 | goto unlock; | 576 | goto unlock; |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 2655ae9a3ad8..ea095abbe97e 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
| @@ -206,8 +206,10 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) | |||
| 206 | retval = pread(fd, msr, sizeof *msr, offset); | 206 | retval = pread(fd, msr, sizeof *msr, offset); |
| 207 | close(fd); | 207 | close(fd); |
| 208 | 208 | ||
| 209 | if (retval != sizeof *msr) | 209 | if (retval != sizeof *msr) { |
| 210 | fprintf(stderr, "%s offset 0x%zx read failed\n", pathname, offset); | ||
| 210 | return -1; | 211 | return -1; |
| 212 | } | ||
| 211 | 213 | ||
| 212 | return 0; | 214 | return 0; |
| 213 | } | 215 | } |
| @@ -1101,7 +1103,9 @@ void turbostat_loop() | |||
| 1101 | 1103 | ||
| 1102 | restart: | 1104 | restart: |
| 1103 | retval = for_all_cpus(get_counters, EVEN_COUNTERS); | 1105 | retval = for_all_cpus(get_counters, EVEN_COUNTERS); |
| 1104 | if (retval) { | 1106 | if (retval < -1) { |
| 1107 | exit(retval); | ||
| 1108 | } else if (retval == -1) { | ||
| 1105 | re_initialize(); | 1109 | re_initialize(); |
| 1106 | goto restart; | 1110 | goto restart; |
| 1107 | } | 1111 | } |
| @@ -1114,7 +1118,9 @@ restart: | |||
| 1114 | } | 1118 | } |
| 1115 | sleep(interval_sec); | 1119 | sleep(interval_sec); |
| 1116 | retval = for_all_cpus(get_counters, ODD_COUNTERS); | 1120 | retval = for_all_cpus(get_counters, ODD_COUNTERS); |
| 1117 | if (retval) { | 1121 | if (retval < -1) { |
| 1122 | exit(retval); | ||
| 1123 | } else if (retval == -1) { | ||
| 1118 | re_initialize(); | 1124 | re_initialize(); |
| 1119 | goto restart; | 1125 | goto restart; |
| 1120 | } | 1126 | } |
| @@ -1126,7 +1132,9 @@ restart: | |||
| 1126 | flush_stdout(); | 1132 | flush_stdout(); |
| 1127 | sleep(interval_sec); | 1133 | sleep(interval_sec); |
| 1128 | retval = for_all_cpus(get_counters, EVEN_COUNTERS); | 1134 | retval = for_all_cpus(get_counters, EVEN_COUNTERS); |
| 1129 | if (retval) { | 1135 | if (retval < -1) { |
| 1136 | exit(retval); | ||
| 1137 | } else if (retval == -1) { | ||
| 1130 | re_initialize(); | 1138 | re_initialize(); |
| 1131 | goto restart; | 1139 | goto restart; |
| 1132 | } | 1140 | } |
| @@ -1545,8 +1553,11 @@ void turbostat_init() | |||
| 1545 | int fork_it(char **argv) | 1553 | int fork_it(char **argv) |
| 1546 | { | 1554 | { |
| 1547 | pid_t child_pid; | 1555 | pid_t child_pid; |
| 1556 | int status; | ||
| 1548 | 1557 | ||
| 1549 | for_all_cpus(get_counters, EVEN_COUNTERS); | 1558 | status = for_all_cpus(get_counters, EVEN_COUNTERS); |
| 1559 | if (status) | ||
| 1560 | exit(status); | ||
| 1550 | /* clear affinity side-effect of get_counters() */ | 1561 | /* clear affinity side-effect of get_counters() */ |
| 1551 | sched_setaffinity(0, cpu_present_setsize, cpu_present_set); | 1562 | sched_setaffinity(0, cpu_present_setsize, cpu_present_set); |
| 1552 | gettimeofday(&tv_even, (struct timezone *)NULL); | 1563 | gettimeofday(&tv_even, (struct timezone *)NULL); |
| @@ -1556,7 +1567,6 @@ int fork_it(char **argv) | |||
| 1556 | /* child */ | 1567 | /* child */ |
| 1557 | execvp(argv[0], argv); | 1568 | execvp(argv[0], argv); |
| 1558 | } else { | 1569 | } else { |
| 1559 | int status; | ||
| 1560 | 1570 | ||
| 1561 | /* parent */ | 1571 | /* parent */ |
| 1562 | if (child_pid == -1) { | 1572 | if (child_pid == -1) { |
| @@ -1568,7 +1578,7 @@ int fork_it(char **argv) | |||
| 1568 | signal(SIGQUIT, SIG_IGN); | 1578 | signal(SIGQUIT, SIG_IGN); |
| 1569 | if (waitpid(child_pid, &status, 0) == -1) { | 1579 | if (waitpid(child_pid, &status, 0) == -1) { |
| 1570 | perror("wait"); | 1580 | perror("wait"); |
| 1571 | exit(1); | 1581 | exit(status); |
| 1572 | } | 1582 | } |
| 1573 | } | 1583 | } |
| 1574 | /* | 1584 | /* |
| @@ -1585,7 +1595,7 @@ int fork_it(char **argv) | |||
| 1585 | 1595 | ||
| 1586 | fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0); | 1596 | fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0); |
| 1587 | 1597 | ||
| 1588 | return 0; | 1598 | return status; |
| 1589 | } | 1599 | } |
| 1590 | 1600 | ||
| 1591 | void cmdline(int argc, char **argv) | 1601 | void cmdline(int argc, char **argv) |
| @@ -1594,7 +1604,7 @@ void cmdline(int argc, char **argv) | |||
| 1594 | 1604 | ||
| 1595 | progname = argv[0]; | 1605 | progname = argv[0]; |
| 1596 | 1606 | ||
| 1597 | while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) { | 1607 | while ((opt = getopt(argc, argv, "+pPSvi:sc:sC:m:M:")) != -1) { |
| 1598 | switch (opt) { | 1608 | switch (opt) { |
| 1599 | case 'p': | 1609 | case 'p': |
| 1600 | show_core_only++; | 1610 | show_core_only++; |
