2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-27 22:53:55 +08:00
linux-next/drivers/usb/host/whci/init.c
Greg Kroah-Hartman 3905118912 USB: host: whci: Remove redundant license text
Now that the SPDX tag is in all USB files, that identifies the license
in a specific and legally-defined manner.  So the extra GPL text wording
can be removed as it is no longer needed at all.

This is done on a quest to remove the 700+ different ways that files in
the kernel describe the GPL license text.  And there's unneeded stuff
like the address (sometimes incorrect) for the FSF which is never
needed.

No copyright headers or other non-license-description text was removed.

Cc: Felipe Balbi <felipe.balbi@linux.intel.com>
Cc: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-07 15:45:02 +01:00

178 lines
4.3 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Wireless Host Controller (WHC) initialization.
*
* Copyright (C) 2007 Cambridge Silicon Radio Ltd.
*/
#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/dma-mapping.h>
#include <linux/uwb/umc.h>
#include "../../wusbcore/wusbhc.h"
#include "whcd.h"
/*
* Reset the host controller.
*/
static void whc_hw_reset(struct whc *whc)
{
le_writel(WUSBCMD_WHCRESET, whc->base + WUSBCMD);
whci_wait_for(&whc->umc->dev, whc->base + WUSBCMD, WUSBCMD_WHCRESET, 0,
100, "reset");
}
static void whc_hw_init_di_buf(struct whc *whc)
{
int d;
/* Disable all entries in the Device Information buffer. */
for (d = 0; d < whc->n_devices; d++)
whc->di_buf[d].addr_sec_info = WHC_DI_DISABLE;
le_writeq(whc->di_buf_dma, whc->base + WUSBDEVICEINFOADDR);
}
static void whc_hw_init_dn_buf(struct whc *whc)
{
/* Clear the Device Notification buffer to ensure the V (valid)
* bits are clear. */
memset(whc->dn_buf, 0, 4096);
le_writeq(whc->dn_buf_dma, whc->base + WUSBDNTSBUFADDR);
}
int whc_init(struct whc *whc)
{
u32 whcsparams;
int ret, i;
resource_size_t start, len;
spin_lock_init(&whc->lock);
mutex_init(&whc->mutex);
init_waitqueue_head(&whc->cmd_wq);
init_waitqueue_head(&whc->async_list_wq);
init_waitqueue_head(&whc->periodic_list_wq);
whc->workqueue = alloc_ordered_workqueue(dev_name(&whc->umc->dev), 0);
if (whc->workqueue == NULL) {
ret = -ENOMEM;
goto error;
}
INIT_WORK(&whc->dn_work, whc_dn_work);
INIT_WORK(&whc->async_work, scan_async_work);
INIT_LIST_HEAD(&whc->async_list);
INIT_LIST_HEAD(&whc->async_removed_list);
INIT_WORK(&whc->periodic_work, scan_periodic_work);
for (i = 0; i < 5; i++)
INIT_LIST_HEAD(&whc->periodic_list[i]);
INIT_LIST_HEAD(&whc->periodic_removed_list);
/* Map HC registers. */
start = whc->umc->resource.start;
len = whc->umc->resource.end - start + 1;
if (!request_mem_region(start, len, "whci-hc")) {
dev_err(&whc->umc->dev, "can't request HC region\n");
ret = -EBUSY;
goto error;
}
whc->base_phys = start;
whc->base = ioremap(start, len);
if (!whc->base) {
dev_err(&whc->umc->dev, "ioremap\n");
ret = -ENOMEM;
goto error;
}
whc_hw_reset(whc);
/* Read maximum number of devices, keys and MMC IEs. */
whcsparams = le_readl(whc->base + WHCSPARAMS);
whc->n_devices = WHCSPARAMS_TO_N_DEVICES(whcsparams);
whc->n_keys = WHCSPARAMS_TO_N_KEYS(whcsparams);
whc->n_mmc_ies = WHCSPARAMS_TO_N_MMC_IES(whcsparams);
dev_dbg(&whc->umc->dev, "N_DEVICES = %d, N_KEYS = %d, N_MMC_IES = %d\n",
whc->n_devices, whc->n_keys, whc->n_mmc_ies);
whc->qset_pool = dma_pool_create("qset", &whc->umc->dev,
sizeof(struct whc_qset), 64, 0);
if (whc->qset_pool == NULL) {
ret = -ENOMEM;
goto error;
}
ret = asl_init(whc);
if (ret < 0)
goto error;
ret = pzl_init(whc);
if (ret < 0)
goto error;
/* Allocate and initialize a buffer for generic commands, the
Device Information buffer, and the Device Notification
buffer. */
whc->gen_cmd_buf = dma_alloc_coherent(&whc->umc->dev, WHC_GEN_CMD_DATA_LEN,
&whc->gen_cmd_buf_dma, GFP_KERNEL);
if (whc->gen_cmd_buf == NULL) {
ret = -ENOMEM;
goto error;
}
whc->dn_buf = dma_alloc_coherent(&whc->umc->dev,
sizeof(struct dn_buf_entry) * WHC_N_DN_ENTRIES,
&whc->dn_buf_dma, GFP_KERNEL);
if (!whc->dn_buf) {
ret = -ENOMEM;
goto error;
}
whc_hw_init_dn_buf(whc);
whc->di_buf = dma_alloc_coherent(&whc->umc->dev,
sizeof(struct di_buf_entry) * whc->n_devices,
&whc->di_buf_dma, GFP_KERNEL);
if (!whc->di_buf) {
ret = -ENOMEM;
goto error;
}
whc_hw_init_di_buf(whc);
return 0;
error:
whc_clean_up(whc);
return ret;
}
void whc_clean_up(struct whc *whc)
{
resource_size_t len;
if (whc->di_buf)
dma_free_coherent(&whc->umc->dev, sizeof(struct di_buf_entry) * whc->n_devices,
whc->di_buf, whc->di_buf_dma);
if (whc->dn_buf)
dma_free_coherent(&whc->umc->dev, sizeof(struct dn_buf_entry) * WHC_N_DN_ENTRIES,
whc->dn_buf, whc->dn_buf_dma);
if (whc->gen_cmd_buf)
dma_free_coherent(&whc->umc->dev, WHC_GEN_CMD_DATA_LEN,
whc->gen_cmd_buf, whc->gen_cmd_buf_dma);
pzl_clean_up(whc);
asl_clean_up(whc);
dma_pool_destroy(whc->qset_pool);
len = resource_size(&whc->umc->resource);
if (whc->base)
iounmap(whc->base);
if (whc->base_phys)
release_mem_region(whc->base_phys, len);
if (whc->workqueue)
destroy_workqueue(whc->workqueue);
}