Commit d19458a4 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 platform updates from Ingo Molnar:
 "Most of the commits are continued SGI UV4 hardware-enablement changes,
  plus there's also new Bluetooth support for the Intel Edison platform"

* 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/platform/intel-mid: Enable Bluetooth support on Intel Edison
  x86/platform/uv/BAU: Implement uv4_wait_completion with read_status
  x86/platform/uv/BAU: Add wait_completion to bau_operations
  x86/platform/uv/BAU: Add status mmr location fields to bau_control
  x86/platform/uv/BAU: Cleanup bau_operations declaration and instances
  x86/platform/uv/BAU: Add payload descriptor qualifier
  x86/platform/uv/BAU: Add uv_bau_version enumerated constants
parents 888411be d4d96990
...@@ -185,6 +185,15 @@ ...@@ -185,6 +185,15 @@
#define MSG_REGULAR 1 #define MSG_REGULAR 1
#define MSG_RETRY 2 #define MSG_RETRY 2
#define BAU_DESC_QUALIFIER 0x534749
enum uv_bau_version {
UV_BAU_V1 = 1,
UV_BAU_V2,
UV_BAU_V3,
UV_BAU_V4,
};
/* /*
* Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor) * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor)
* If the 'multilevel' flag in the header portion of the descriptor * If the 'multilevel' flag in the header portion of the descriptor
...@@ -222,20 +231,32 @@ struct bau_local_cpumask { ...@@ -222,20 +231,32 @@ struct bau_local_cpumask {
* the s/w ack bit vector ] * the s/w ack bit vector ]
*/ */
/* /**
* The payload is software-defined for INTD transactions * struct uv1_2_3_bau_msg_payload - defines payload for INTD transactions
* @address: Signifies a page or all TLB's of the cpu
* @sending_cpu: CPU from which the message originates
* @acknowledge_count: CPUs on the destination Hub that received the interrupt
*/ */
struct bau_msg_payload { struct uv1_2_3_bau_msg_payload {
unsigned long address; /* signifies a page or all u64 address;
TLB's of the cpu */ u16 sending_cpu;
/* 64 bits */ u16 acknowledge_count;
unsigned short sending_cpu; /* filled in by sender */
/* 16 bits */
unsigned short acknowledge_count; /* filled in by destination */
/* 16 bits */
unsigned int reserved1:32; /* not usable */
}; };
/**
* struct uv4_bau_msg_payload - defines payload for INTD transactions
* @address: Signifies a page or all TLB's of the cpu
* @sending_cpu: CPU from which the message originates
* @acknowledge_count: CPUs on the destination Hub that received the interrupt
* @qualifier: Set by source to verify origin of INTD broadcast
*/
struct uv4_bau_msg_payload {
u64 address;
u16 sending_cpu;
u16 acknowledge_count;
u32 reserved:8;
u32 qualifier:24;
};
/* /*
* UV1 Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor) * UV1 Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor)
...@@ -385,17 +406,6 @@ struct uv2_3_bau_msg_header { ...@@ -385,17 +406,6 @@ struct uv2_3_bau_msg_header {
/* bits 127:120 */ /* bits 127:120 */
}; };
/* Abstracted BAU functions */
struct bau_operations {
unsigned long (*read_l_sw_ack)(void);
unsigned long (*read_g_sw_ack)(int pnode);
unsigned long (*bau_gpa_to_offset)(unsigned long vaddr);
void (*write_l_sw_ack)(unsigned long mmr);
void (*write_g_sw_ack)(int pnode, unsigned long mmr);
void (*write_payload_first)(int pnode, unsigned long mmr);
void (*write_payload_last)(int pnode, unsigned long mmr);
};
/* /*
* The activation descriptor: * The activation descriptor:
* The format of the message to send, plus all accompanying control * The format of the message to send, plus all accompanying control
...@@ -411,7 +421,10 @@ struct bau_desc { ...@@ -411,7 +421,10 @@ struct bau_desc {
struct uv2_3_bau_msg_header uv2_3_hdr; struct uv2_3_bau_msg_header uv2_3_hdr;
} header; } header;
struct bau_msg_payload payload; union bau_payload_header {
struct uv1_2_3_bau_msg_payload uv1_2_3;
struct uv4_bau_msg_payload uv4;
} payload;
}; };
/* UV1: /* UV1:
* -payload-- ---------header------ * -payload-- ---------header------
...@@ -588,8 +601,12 @@ struct uvhub_desc { ...@@ -588,8 +601,12 @@ struct uvhub_desc {
struct socket_desc socket[2]; struct socket_desc socket[2];
}; };
/* /**
* one per-cpu; to locate the software tables * struct bau_control
* @status_mmr: location of status mmr, determined by uvhub_cpu
* @status_index: index of ERR|BUSY bits in status mmr, determined by uvhub_cpu
*
* Per-cpu control struct containing CPU topology information and BAU tuneables.
*/ */
struct bau_control { struct bau_control {
struct bau_desc *descriptor_base; struct bau_desc *descriptor_base;
...@@ -607,6 +624,8 @@ struct bau_control { ...@@ -607,6 +624,8 @@ struct bau_control {
int timeout_tries; int timeout_tries;
int ipi_attempts; int ipi_attempts;
int conseccompletes; int conseccompletes;
u64 status_mmr;
int status_index;
bool nobau; bool nobau;
short baudisabled; short baudisabled;
short cpu; short cpu;
...@@ -644,6 +663,19 @@ struct bau_control { ...@@ -644,6 +663,19 @@ struct bau_control {
struct hub_and_pnode *thp; struct hub_and_pnode *thp;
}; };
/* Abstracted BAU functions */
struct bau_operations {
unsigned long (*read_l_sw_ack)(void);
unsigned long (*read_g_sw_ack)(int pnode);
unsigned long (*bau_gpa_to_offset)(unsigned long vaddr);
void (*write_l_sw_ack)(unsigned long mmr);
void (*write_g_sw_ack)(int pnode, unsigned long mmr);
void (*write_payload_first)(int pnode, unsigned long mmr);
void (*write_payload_last)(int pnode, unsigned long mmr);
int (*wait_completion)(struct bau_desc*,
struct bau_control*, long try);
};
static inline void write_mmr_data_broadcast(int pnode, unsigned long mmr_image) static inline void write_mmr_data_broadcast(int pnode, unsigned long mmr_image)
{ {
write_gmmr(pnode, UVH_BAU_DATA_BROADCAST, mmr_image); write_gmmr(pnode, UVH_BAU_DATA_BROADCAST, mmr_image);
......
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
obj-$(subst m,y,$(CONFIG_PINCTRL_MERRIFIELD)) += platform_mrfld_pinctrl.o obj-$(subst m,y,$(CONFIG_PINCTRL_MERRIFIELD)) += platform_mrfld_pinctrl.o
# SDHCI Devices # SDHCI Devices
obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += platform_mrfld_sd.o obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += platform_mrfld_sd.o
# WiFi # WiFi + BT
obj-$(subst m,y,$(CONFIG_BRCMFMAC_SDIO)) += platform_bcm43xx.o obj-$(subst m,y,$(CONFIG_BRCMFMAC_SDIO)) += platform_bcm43xx.o
obj-$(subst m,y,$(CONFIG_BT_HCIUART_BCM)) += platform_bt.o
# IPC Devices # IPC Devices
obj-$(subst m,y,$(CONFIG_MFD_INTEL_MSIC)) += platform_msic.o obj-$(subst m,y,$(CONFIG_MFD_INTEL_MSIC)) += platform_msic.o
obj-$(subst m,y,$(CONFIG_SND_MFLD_MACHINE)) += platform_msic_audio.o obj-$(subst m,y,$(CONFIG_SND_MFLD_MACHINE)) += platform_msic_audio.o
......
/*
* Bluetooth platform data initialization file
*
* (C) Copyright 2017 Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include <linux/gpio/machine.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
#include <asm/intel-mid.h>
struct bt_sfi_data {
struct device *dev;
const char *name;
int (*setup)(struct bt_sfi_data *ddata);
};
static struct gpiod_lookup_table tng_bt_sfi_gpio_table = {
.dev_id = "hci_bcm",
.table = {
GPIO_LOOKUP("0000:00:0c.0", -1, "device-wakeup", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("0000:00:0c.0", -1, "shutdown", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("0000:00:0c.0", -1, "host-wakeup", GPIO_ACTIVE_HIGH),
{ },
},
};
#define TNG_BT_SFI_GPIO_DEVICE_WAKEUP "bt_wakeup"
#define TNG_BT_SFI_GPIO_SHUTDOWN "BT-reset"
#define TNG_BT_SFI_GPIO_HOST_WAKEUP "bt_uart_enable"
static int __init tng_bt_sfi_setup(struct bt_sfi_data *ddata)
{
struct gpiod_lookup_table *table = &tng_bt_sfi_gpio_table;
struct gpiod_lookup *lookup = table->table;
struct pci_dev *pdev;
/* Connected to /dev/ttyS0 */
pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(4, 1));
if (!pdev)
return -ENODEV;
ddata->dev = &pdev->dev;
ddata->name = table->dev_id;
lookup[0].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_DEVICE_WAKEUP);
lookup[1].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_SHUTDOWN);
lookup[2].chip_hwnum = get_gpio_by_name(TNG_BT_SFI_GPIO_HOST_WAKEUP);
gpiod_add_lookup_table(table);
return 0;
}
static struct bt_sfi_data tng_bt_sfi_data __initdata = {
.setup = tng_bt_sfi_setup,
};
#define ICPU(model, ddata) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (kernel_ulong_t)&ddata }
static const struct x86_cpu_id bt_sfi_cpu_ids[] = {
ICPU(INTEL_FAM6_ATOM_MERRIFIELD, tng_bt_sfi_data),
{}
};
static int __init bt_sfi_init(void)
{
struct platform_device_info info;
struct platform_device *pdev;
const struct x86_cpu_id *id;
struct bt_sfi_data *ddata;
int ret;
id = x86_match_cpu(bt_sfi_cpu_ids);
if (!id)
return -ENODEV;
ddata = (struct bt_sfi_data *)id->driver_data;
if (!ddata)
return -ENODEV;
ret = ddata->setup(ddata);
if (ret)
return ret;
memset(&info, 0, sizeof(info));
info.fwnode = ddata->dev->fwnode;
info.parent = ddata->dev;
info.name = ddata->name,
info.id = PLATFORM_DEVID_NONE,
pdev = platform_device_register_full(&info);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
dev_info(ddata->dev, "Registered Bluetooth device: %s\n", ddata->name);
return 0;
}
device_initcall(bt_sfi_init);
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment